[英]Traversing Neo4j graph in increasing order of relationship weights using Cypher
如@FrankPavageau所述,用Java編寫解決方案的編碼可能不太麻煩,而且速度更快。 不過,通過利用現有的APOC過程apoc.periodic.commit ,您無需在Java中實現任何東西。
apoc.periodic.commit
將重復執行Cypher查詢, 直到返回值0或根本沒有結果 。 這是如何使用它來解決問題的示例。
首先,讓我們創建示例數據:
CREATE (a:Foo {id: 'a'}), (b:Foo {id: 'b'}), (c:Foo {id: 'c'}), (d:Foo {id: 'd'}), (e:Foo {id: 'e'}), (f:Foo {id: 'f'}), (g:Foo {id: 'g'}),
(a)-[:NEXT {value: 3}]->(b),
(a)-[:NEXT {value: 4}]->(e),
(e)-[:NEXT {value: 3}]->(c),
(e)-[:NEXT {value: 1}]->(f),
(e)-[:NEXT {value: 2}]->(g),
(c)-[:NEXT {value: 3}]->(d),
(c)-[:NEXT {value: 2}]->(g);
此技術涉及您3個查詢:
創建帶有Temp
標簽的臨時節點的查詢(在下面的步驟2中執行的重復執行之間保持狀態,並保留最終結果)。 (在采樣數據中,起始節點具有一個id
的a
。)
MERGE (temp:Temp) SET temp = {values: [], ids: ['a']};
調用apoc.periodic.commit
的查詢以重復執行傳遞的Cypher語句。 每次執行的Cypher語句時,它會從最后找到的節點(其的一個開始id
是在尾部temp.ids
),並試圖尋找下一個節點,其關系具有最高value
的價值。 如果最后一個節點是葉節點,則Cypher語句不返回任何內容(因為第二個MATCH
將失敗,從而中止該語句)-這將終止該過程; 否則,Cypher語句會將max
附加到temp.values
,並將相應的節點id
附加到temp.ids
,並返回1。
CALL apoc.periodic.commit(" MATCH (temp:Temp) MATCH (:Foo {id: LAST(temp.ids)})-[n:NEXT]->(f:Foo) WITH temp, REDUCE(s = {max: 0}, x IN COLLECT({v: n.value, id: f.id}) | CASE WHEN xv > s.max THEN {max: xv, id: x.id} ELSE s END ) AS curr SET temp.values = temp.values + curr.max, temp.ids = temp.ids + curr.id RETURN 1; ", NULL);
查詢以獲取最終結果。 ids
集合將是“最大路徑”上節點的id,而values
集合將是同一條路徑上NEXT
關系的values
。
MATCH (temp:Temp) RETURN temp;
結果如下:
╒══════════════════════════════════════╕
│temp │
╞══════════════════════════════════════╡
│{values: [4, 3, 3], ids: [a, e, c, d]}│
└──────────────────────────────────────┘
您的描述有些錯誤(根據您的示例),因為您不想遍歷關系的權重不斷增加 ,因此您想遍歷每一步中權重最大的關系。
您無法在Cypher中以通用方式執行此操作,因為結果是迭代生成的,並且您不知道結果路徑的最大長度。
在Cypher中,您必須
Cypher的聲明性本質上並不能真正兼容:這將很麻煩,並且可能也會很慢。 構建一個遍歷最長路徑的過程或函數(在即將到來的Neo4j 3.1中)會容易得多,而PathExpander
僅返回當前節點具有最大權重的關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.