簡體   English   中英

Neo4j-查找從未與其他節點有任何關系的節點

[英]Neo4j - Find nodes who never had any relationship with a different node

假設我有一個帶有這樣的節點和關系的示例:

(:Node_A) -[:rel_a]-> (:Node_B) -[:rel_b]-> (:Node_C)

我想找到從未與(:Node_C {label:'A'})有關系的Node_A所有節點。

我試過了:

MATCH (a:Node_A) -[:rel_a]-> (b:Node_B), (c:Node_C {label:'A'})
WHERE NOT (b) -[:rel_b]-> (c)
RETURN a

但是我沒有得到預期的結果。

如果我具有這些節點和關系,則不希望返回node_a

(node_a:Node_A) -[:rel_a]-> (b1:Node_B),
(node_a:Node_A) -[:rel_a]-> (b2:Node_B),

(b1:Node_B) -[:rel_b]-> (c:Node_C {label:'A'}),
(b1:Node_B) -[:rel_b]-> (c1:Node_C {label:'B'}),

(b2:Node_B) -[:rel_b]-> (c2:Node_C {label:'C'})

如何匹配從未與(:Node_C {label:'A'})沒有任何關系的節點?

之所以沒有得到預期的結果,是因為存在與給定模式匹配的路徑(一個Node_A節點連接到Node_B節點,因此Node_B節點未連接到label:'A'Node_C節點)。 這是因為,根據示例圖的描述,您有2個:Node_B節點連接到您的單個:Node_A節點。 其中一個連接到兩個:Node_C節點,其中一個是您要避免的:Node_C節點(在這種情況下,由於您的WHERE子句,帶有該:Node_B節點的THAT路徑被過濾掉了),並且其他:Node_B節點連接到帶有標簽'C'的安全:Node_C節點,這是適合您的查詢並返回的路徑。

您可以通過幾種方式獲得所需的過濾條件。

一種是在WHERE子句中定義要完全排除的完整模式,然后將:Node_B部分保留在MATCH子句之外:

MATCH (a:Node_A), (c:Node_C {label:'A'})
WHERE NOT (a) -[:rel_a]-> (:Node_B) -[:rel_b]-> (c)
RETURN a

如果您不了解或不關心中間節點或ac之間a關系,則可以從模式中省略它們:

MATCH (a:Node_A), (c:Node_C {label:'A'})
WHERE NOT (a) --> () --> (c)
RETURN a

您可以使用可變長度關系表示同一件事,其中我們知道c只能相距2跳:

MATCH (a:Node_A), (c:Node_C {label:'A'})
WHERE NOT (a) -[*2]-> (c)
RETURN a

編輯

stdob--正確地指出,對於所有這些方法,我們假設圖中存在帶有label:'A':Node_C節點。 如果不能保證這一點,並且碰巧沒有這樣的節點,那么這些查詢將不會返回任何內容。

如果我們必須處理這種潛在的情況,那么最好將其從MATCH移到WHERE子句中:

MATCH (a:Node_A)
WHERE NOT (a) -[*2]-> (:Node_C {label:'A'})
RETURN a

實際上,在任何情況下這都是一件好事,好像我們有多個這樣的節點,而不是只有一個這樣的節點,如果將其保留在MATCH子句中,可能會弄亂我們的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM