2017-05-04 34 views
2

我已經follwing簡單的圖形:獲取葉的第一根中的Neo4j

CREATE (:leaf)<-[:rel]-(:nonleaf)<-[:rel]-(:nonleaf)<-[:rel]-(:nonleaf)<-[:rel]-(r1:nonleaf{root:true})<-[:rel]-(r2:nonleaf{root:true}) 

我想開始從(:leaf)root:true在其上設置始祖。那是我想要得到r1。爲此,我寫了下面的暗號:

MATCH (:leaf)<-[*]-(m)<-[*]-(r:nonleaf{root:true}) WHERE m.root<>true OR NOT exists(m.root) 
RETURN r 

但它同時返回(r1)(r2)。同樣發生的後續密碼:

MATCH shortestPath((l:leaf)<-[*]-(r:nonleaf{root:true})) 
RETURN r 

這是怎麼回事?

更新
好的思維更後,點擊它給我記住,(r2)也被返回因爲路徑從(:leaf)(r2),有這應該已經單擊以我早期沒有root財產對他們(設置節點,非常明顯,微妙的解釋錯誤)。換句話說,如果「至少有一個m條件成立:m.root<>true OR NOT exists(m.root),則返回(:nonleaf{root:true})。這裏的要求是條件應該對路徑上的「全部m s」「不是至少一個m有效。現在仍然要弄清楚如何把它放在密碼中,而我對密碼的掌握並不是那麼緊密......

回答

1

您可以通過single()謂詞函數的幫助強制在匹配路徑上存在單個根節點:

MATCH p=(:leaf)<-[*]-(r:nonleaf{root:true}) 
WHERE SINGLE(m IN nodes(p) WHERE exists(m.root) AND m.root=true) 
RETURN r 
1

你只需要調整你的WHERE條件一點,所以,它說「和匹配根:nonleaf節點之前的:nonleaf節點本身不是標記爲根節點」。我認爲這將滿足您的需求。

MATCH (l:leaf)<-[*]-(r:nonleaf {root: true}) 
WHERE NOT (:nonleaf {root: true})<--(r) 
RETURN r 

修訂

閱讀在評論中更新的例子,我想到了另一種方式來解決使用過程APOC您apoc.path.expandConfig問題。

它確實需要對您的數據進行輕微更改。每個root: true節點應該在其上設置一個:root標籤。下面是一個更新語句...

MATCH (n:nonleaf {root:true}) 
SET n:root 
RETURN n 

,這裏是更新查詢

MATCH (leaf:leaf {name: 'leaf'}) 
WITH leaf 
CALL apoc.path.expandConfig(leaf, {relationshipFilter:'<rel',labelFilter:'/root'}) yield path 
RETURN last(nodes(path)) 
+0

我想這會爲失敗:'CREATE(:葉)< - [:REL] - (:非葉)< - [:相對] - (:非葉)< - [:REL] - (:非葉)< - [:相對] - (R 1:非葉{根:真})< - [:相對] - (:非葉)< - [:REL] - (R2:非葉根{:真})'。它會返回'(r1)'和'(r2)'。對? – Mahesha999

+0

你試過了嗎? –

+0

是的。看起來你認爲下面不會發生:'(nonroot)< - (root)< - (nonroot)< - (root)'。在這種情況下,兩個根都會返回,但我只需要最左側的根。那就是我用新的CREATE來評論的。試試這些:CREATE(:leaf {id:'leaf1'})< - [:rel] - (:nonleaf)< - [:rel] - (:nonleaf)< - [:rel] - (:nonleaf)< - [:rel] - (r1:nonleaf {root:true})< - [:rel] - (:nonleaf)< - [:rel] - (r2:nonleaf {root:true})' ::葉{{:葉1'})< - [*] - (r:nonleaf {root:true})WHERE NOT(:nonleaf {root:true})< - (r)RETURN r'。無論如何,萊昂的答案似乎是確切的。 – Mahesha999