2017-06-02 130 views
1

我有一個簡單的查詢尋找與許多起始節點a,b,c有關的公共節點'x'。如果a,b,c沒有公共節點x,那麼我只想比較公共節點'y'和'z'的a,b和b,c。這是我應該看起來的想法......但當然不起作用。與MATCH一起使用CASE

MATCH p1=(a)-[]->(x) WHERE a.n=1 
WITH p1,a,x 
MATCH p2=(b)-[]->(x) WHERE b.n=2 
WITH p1,p2,a,b,x 
MATCH p3=(c)-[]->(x) WHERE c.n=3 
WITH p1,p2,p3,a,b,c,x 
MATCH CASE WHEN x IS NULL THEN p4=(a)-[]->(y)<-[]-(b) WHERE a.n=1 AND b.n=2 END 
WITH p1,p2,p3,p4,a,b,c,x,y 
MATCH CASE WHEN x IS NULL THEN p5=(b)-[]->(z)<-[]-(c) WHERE b.n=2 AND c.n=3 END 
RETURN p1,p2,p3,p4,p5,x,y,z 

我期待在使用CASE,以減少冗餘和加快查詢,因爲沒有必要在對的,B B進行搜索,C,如果一個共同的「X」被發現。你如何使用CASE來創建一個MATCH。也許有比使用CASE更好的方法?

問題背景

我有一個非常大的數據集是很淺的平均15個節點深。我正在尋找網絡中公共相關節點形式的多個輸入之間的相關性。輸入可以從2到20個連續值編號,它們的順序是相關的,因爲它們傾向於以相關的方式組合在一起。很多時候,所有的輸入都會有一個共同的相關節點,但如果不是,我需要找到其他具有共同節點的順序分組,即輸入1,2 | 2,3 | 3,4,5等等。所以這是一個問題,究竟是從廣泛的開始,還是從一開始就將成對的下一個輸入與最後一個的輸入進行比較。我希望能夠使用CASE來做出關於在沒有找到結果的情況下通過輸入進行分組的工作的決定。

就構建網絡而言,每個節點具有最少的關係數量都很淺,因此添加元節點可能無濟於事。將輸入組合成一個單一的起始節點只會以指數形式增加起始節點的數量,此時每個可能的輸入都有一個 - 一千萬左右。將它們組合起來會以指數級增加,所以我認爲最好避免,因爲我的理解是查找起始節點是查詢中最昂貴的部分。對不起,我一定不會談論商業案例。

回答

2

該查詢應返回x,y和z值的集合。如果xs集合不爲空,則可以選擇忽略yszs集合。

MATCH (a {n: 1}), (b {n: 2})-->(w), (c {n: 3}) 
OPTIONAL MATCH pa=(a)-->(w) 
WITH a, b, c, COLLECT(DISTINCT NODES(pa)[1]) AS ys 
OPTIONAL MATCH pc=(c)-->(w) 
WITH a, b, c, ys, COLLECT(DISTINCT NODES(pc)[1]) AS zs 
RETURN a, b, c, apoc.coll.intersection(ys, zs) AS xs, ys, zs; 

需要注意你的使用情況而有趣的是,b節點需要確定所有3個集的內容。因此,MATCH子句找到與b節點相關的節點,並將其他(可選)匹配限制爲僅考慮這些節點 - 這應該加快查詢速度。 APOC功能apoc.coll.intersection用於與yszs集合相交以獲得集合xs

[EDITED]

相反在相同的時間(在第二可選匹配之後)執行兩個COLLECT操作,我們是第一個可選匹配後立即執行第一COLLECT操作,使得我們能夠避免笛卡爾乘積。這應該加快查詢並減少內存需求。

+0

謝謝。我試圖在可能的情況下避免2節點匹配,因爲它可能會返回1000行 - 而3+節點匹配應該只返回幾行。我沒有安裝APOC版本,但是您是否覺得每次匹配1000行都是最快的,而不是先嚐試所有啓動節點上的匹配,然後跳過2個節點匹配?在這個例子中有3個啓動節點,但在使用中可能有20個。 – Damon

+2

你能否更新你的問題以提供關於你的用例的完整細節?否則無法提供良好的答案。 (例如,如果有20個節點,那麼可能的節點分組是什麼?)甚至有可能有另一種方法來構造數據以有效地獲得結果,但我們需要知道您的用例。 – cybersam

+0

好的,謝謝,我已經更新了有關數據的更多信息。 – Damon

2

對於那些沒有獲得APOC,這裏是薩姆斯answer平原Cypher支架版本

// Get Start Nodes 
MATCH (a {n: 1}), (b {n: 2}), (c {n: 3}) 

// Find common nodes for ab and cb 
OPTIONAL MATCH (a)-->(ab)<--(b) 
OPTIONAL MATCH (c)-->(cb)<--(b) 

// Aggregate common nodes of ab and cb 
WITH a, b, c, COLLECT(ab) AS ab, COLLECT(cb) AS cb 

// Return with additional Aggregate of intersection of the lists ab and cb 
RETURN a, b, c, filter(n in ab WHERE n IN cb) as abc, ab, cb 
+0

謝謝你。我在版本2.3,所以沒有APOC。我收到錯誤:「類型不匹配:預期的路徑,但是收集(第5行,第35列) 」返回a,b,c,過濾器(n在NODES(ab)WHERE n IN cb)作爲abc,ab, cb「」 – Damon

+0

@Damon對不起,習慣。做了NODES(ab)而不是ab(ab已經是節點列表) – Tezra