2017-02-11 89 views
0

我開始使用Neo4j,並想知道如何找到連接到另一個節點的節點,長度至多爲k個邊緣(朋友的朋友的朋友......最多k次)。我將以Neo4j本身的教程爲例來說明(我把圖形創建命令放在最下面)。Cypher阻止列舉所有路徑

match (e {name:"Emil"})-[*1..2]-(p) 
return DISTINCT e, p; 

該查詢將返回連接到埃米爾和連接到這些節點的節點的節點。我的問題是,它似乎枚舉Emil長度爲1-2的每條路徑,但我並不關心列舉所有路徑。從查詢中可以明顯看出,我只關心在那個距離連接到Emil的節點,並且枚舉所有可能的路徑是實現該查詢的一種很差的方式。隨着複雜性變得非常強大,這是一個大型密集圖形的問題。

刪除DISTINCT,將會有8條記錄,這是來自Emil的唯一的1-2長度路徑的數量。根據我在較大圖上的測試,似乎DISTINCT是一個後處理步驟,不會影響查詢的運行時間,儘管它會消除冗餘輸出。那是對的嗎?

我的主要問題是,有沒有一種方法可以爲這個問題形成一個Cypher查詢,這樣我就不會遍歷所有的獨特路徑,複雜性可以降低?請讓我知道我是否也有誤解。

----命令來創建圖形-----

CREATE (ee:Person { name: "Emil", from: "Sweden", klout: 99 }) 
CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }), 
(ir:Person { name: "Ian", from: "England", title: "author" }), 
(rvb:Person { name: "Rik", from: "Belgium", pet: "Orval" }), 
(ally:Person { name: "Allison", from: "California", hobby: "surfing" }), 
(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir), 
(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb), 
(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally), 
(rvb)-[:KNOWS]->(ally) 

回答

0

最大德Marzi在新寫了一個偉大的blog post這些類型的查詢,所以可變長度的比賽,唯一的興趣是對於不同的節點,而不是路徑,將在未來的版本中由查詢規劃器進行檢測和優化,可能爲3.2。

與此同時,當您提供'NODE_GLOBAL'作爲唯一性參數時,APOC程序在它們的apoc.path.expandConfig()調用中有一個解決方案。

這將確保在路徑擴展期間找到的節點只訪問一次,因此您不應該看到到同一節點的多條路徑。

match (e {name:"Emil"}) 
call apoc.path.expandConfig(e, {maxLevel:2, uniqueness:'NODE_GLOBAL'}) yield path 
WITH e, last(nodes(path)) as subgraph 
where e <> subgraph 
return e, subgraph; 
+0

謝謝!兩者都是我正在尋找的。 – steve