2016-11-28 80 views
1

考慮我有下面的圖表與邊權:穿越的Neo4j圖形的Cypher

enter image description here

我想知道我是否可以進行遍歷起始節點和以下的邊緣隨使用CYPHER的重量順序。這是它應該返回(a)-4->(e)-3->(c)-3->(d)

這可能使用密碼?

回答

1

您的描述稍有不當(根據你的例子),因爲你不想遍歷與關係越來越重,要遍歷與最大重量在每一步的關係(S) 。

你不能在Cypher中以通用的方式完成它,因爲結果是迭代構建的,而且你無法知道結果路徑的最大長度。

在暗號,你就必須

  1. 構建所有路徑
  2. 第一關係
  3. 過濾器由第二關係的加權其餘的重量進行篩選(其如果存在的話)

Cypher支架的聲明性質是不是真的兼容:它會很麻煩,並可能很慢。建立一個procedure或函數(在即將到來的Neo4j 3.1中)traversing最長的路徑將變得容易得多,而PathExpander只返回與來自當前節點的最大權重的關係。

+0

所以基本上我不得不求助於只和最好遍歷API在存儲過程編寫API代碼爲你解釋[我這個問題(HTTP ://stackoverflow.com/questions/40720077/using-neo4j-traversal-api-to-perform-traversal-on-neo4j-running-on-other-machine)...? – Mahesha999

+0

我認爲這是一個更好的工具,是的。 –

2

正如@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個查詢你的一部分:

  1. 查詢創建具有Temp標籤臨時節點(持久化狀態在下面的步驟2中執行的重複執行之間,並保持最終結果)。 (在採樣數據中,起始節點具有一個aid。)

    MERGE (temp:Temp) 
    SET temp = {values: [], ids: ['a']}; 
    
  2. 查詢調用apoc.periodic.commit以執行所傳遞的Cypher支架語句的重複執行。每次執行Cypher語句時,它將從最後找到的節點(id位於temp.ids的末尾)開始,並嘗試查找其關係具有最高值的下一個節點。如果最後一個節點是葉節點,則Cypher語句不返回任何內容(因爲第二個MATCH將失敗,中止該語句) - 這將終止該過程;否則,Cypher支架聲明將追加maxtemp.values和相應的節點idtemp.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 x.v > s.max 
         THEN {max: x.v, id: x.id} 
         ELSE s 
        END 
    ) AS curr 
        SET temp.values = temp.values + curr.max, temp.ids = temp.ids + curr.id 
        RETURN 1; 
    ", NULL); 
    
  3. 查詢得到最終結果。 ids集合將是沿着「最大路徑」的節點的ID,並且values集合將是沿相同路徑的NEXT關係的values

    MATCH (temp:Temp) 
    RETURN temp; 
    

下面是結果:

╒══════════════════════════════════════╕ 
│temp         │ 
╞══════════════════════════════════════╡ 
│{values: [4, 3, 3], ids: [a, e, c, d]}│ 
└──────────────────────────────────────┘