2017-03-27 66 views
5

我有一個在Neo中有5億個節點和邊的圖。我想找到避免超節點的2個節點之間的最短路徑(即使它們比具有超節點的路徑長)。Neo4j中沒有超節點的最短路徑

下面的查詢工作正常較小的圖形,但從來沒有完成對我處理大小的圖表:

MATCH (n:Node { id:'123'}),(m:Node { id:'234' }), p = shortestPath((n)-[*..6]-(m)) 
WHERE NONE(x IN NODES(p) WHERE size((x)--())>1000) 
RETURN p 

如果我刪除WHERE子句是超級快。通常是亞秒。

我該如何加快速度?預先計算節點度並索引它們會有幫助嗎?我是否應該複製所有與超節點相鄰的邊,並給它們一個新的標籤,並將它們用於我的shortestPath查詢而不使用WHERE子句?還有其他建議嗎?

+0

會發生什麼事,如果你刪除標籤? (x) - ())> 1000) –

+0

好點。道歉,我實際上在WHERE子句中沒有標籤測試它。第一個標籤有錯誤。第二個標籤似乎沒有任何區別。讓我更新我的問題以刪除標籤。作爲參考它最初看起來像這樣: WHERE NONE(x:Node IN NODES(p)WHERE size((x:Node) - ())> 1000) – Tom

回答

2

據我所知,當WHERE ALL僅包含關係(而不是節點)時,Neo4j最短路徑實現修剪路徑。如果它不能修剪查詢,它會找到所有的路徑然後過濾它們(慢)。

正如馬丁說,你可以添加一個標籤:

MATCH (x:Node) 
WHERE size((x)--())>1000 
SET n:Supernode 

,然後通過邊詢問節點的標籤:

MATCH p = shortestPath((n:Node { id:'1'})-[*..6]-(m:Node { id:'2' })) 
WHERE ALL(rel IN relationships(p) WHERE not (startNode(rel):Supernode or endNode(rel):Supernode)) 
RETURN p 

這將使Neo4j的使用進行了優化,雙向,寬度優先(快速)查詢。

一些更多的閱讀這裏: https://neo4j.com/docs/developer-manual/current/cypher/execution-plans/shortestpath-planning/

2

你也可以嘗試添加一個標籤爲超:

MATCH (x:Node) 
WHERE size((x)--())>1000 
SET n:Supernode 

請問您的數據這一運行並完成?你有多少個超節點和正常節點?

然後嘗試:

MATCH (n:Node { id:'123'}),(m:Node { id:'234' }) 
WITH n, m 
MATCH p = shortestPath((n)-[*..6]-(m)) 
WHERE NONE(x IN NODES(p) WHERE (x:Supernode)) 
RETURN p 

我想一個標籤檢查速度更快。

+0

謝謝。這並不能解決問題,但它很有用。所以我有幾乎0.5G的節點。我能夠在9米內運行第一個查詢來標記超節點。其中有525個(即程度> 1k)。 不幸的是,如果在節點n和m之間有一個超節點,那麼第二個查詢仍然是永久的。據我所知,如果在這些節點附近沒有超級節點,速度非常快。 – Tom

相關問題