2015-10-13 28 views
0

我有一個帶有定向循環的Neo4j圖。我有沒有問題找到的A所有後代假設我不關心使用這個暗號查詢循環:使用關係屬性作爲過濾器的導向循環的遍歷圖

match (n:TEST{name:"A"})-[r:MOVEMENT*]->(m:TEST) 
return n,m,last(r).movement_time 

的關係我的節點之間有一個timestamp屬性在他們身上,movement_time。我在下面的測試數據中使用我已經作爲浮點數導入的數字進行了模擬。我想使用時間戳作爲約束來遍歷圖。只有跟隨帶來我們到這個節點的關係的移動時間有更大的移動時間的關係。

這裏是CSV樣本數據:

from,to,movement_time 
A,B,0 
B,C,1 
B,D,1 
B,E,1 
B,X,2 
E,A,3 
Z,B,5 
C,X,6 
X,A,7 
D,A,7 

這裏是圖的樣子:

Graph

我想計算出圖中每個節點的後代,包括使用Cypher的最後一次關係的時間戳;所以我想我的輸出數據看東西這樣的:

Node:[{Descendant,Movement Time},...] 
A:[{B,0},{C,1},{D,1},{E,1},{X,2}] 
B:[{C,1},{D,1},{E,1},{X,2},{A,7}] 
C:[{X,6},{A,7}] 
D:[{A,7}] 
E:[{A,3}] 
X:[{A,7}] 
Z:[{B,5}] 

-Neo4J實現類似於我想要做的事:Cycle enumeration of a directed graph with multi edges

回答

1

這個人是不是100%你想要什麼,但非常接近:

MATCH (n:TEST)-[r:MOVEMENT*]->(m:TEST) 
WITH n, m, r, [x IN range(0,length(r)-2) | 
    (r[x+1]).movement_time - (r[x]).movement_time] AS deltas 
WHERE ALL (x IN deltas WHERE x>0) 
RETURN n, collect(m), collect(last(r).movement_time) 
ORDER BY n.name 

我們基本上找到所有你的任何節點之間的路徑(注意笛卡爾的產品會非常昂貴的非平凡DAT asets)。在WITH中,我們正在構建一個集合delta's,該集合保留了兩個後續movement_time屬性之間的差異。

WHERE應用ALL謂詞來過濾掉那些具有任何非正值的值 - 也就是說我們保證沿路徑增加值movement_time

RETURN然後只是組裝結果 - 但不是作爲地圖,而是一個可達節點的集合和最後一個值movement_time

目前的問題是,我們有重複,因爲例如,有從BA的多條路徑。

作爲一般說明:通過使用Java遍歷API(http://neo4j.com/docs/stable/tutorial-traversal.html),此問題更加優雅和更高性能。在這裏,您將擁有一個PathExpander,它可以在早期跳過路徑並減少movement_time,而不是收集全部並過濾掉(如Cypher所做的那樣)。

+0

哦,這很好!我同意,這不是100%完美,但我認爲它會完成這項工作。一旦它回來,我將解析結果,創建名稱和移動時間對,然後得到它們的不同組。這將擺脫我的重複,應該是我所追求的。我會玩弄它並讓你知道。 – Peter

+0

在測試這個工作,並修剪重複不是一個問題;但我同意使用Java遍歷將會好得多,並且對於大型圖表來說是高性能的。我想我會試着讓Java實現工作。 – Peter