2016-07-21 76 views
3

我有一個暗號查詢是這樣的:我的暗號WHERE子句不過濾

MATCH(e:ZOOT {id:100}) 
OPTIONAL MATCH(e)-[a1]->(X:QAZ) 
OPTIONAL MATCH(e)-[a2]->(Y:WSX) 
WHERE a1 is not null or a2 is not null 
RETURN e, a1, a2 

我想要的是用於生產的行既不被過濾掉a1a2

然而,我的聲明在所有情況下都返回行,即使是a1a2都是null。

WHERE是如何工作的?

編輯 - 澄清添加到查詢

+0

您可能希望重新閱讀有關標籤使用和匹配查詢中關係的文檔。現在,e,a1,a2,X和Y都是變量,並且您在查詢中沒有使用任何標籤或關係名稱,因此它與您的數據庫中的每個具有任何種類與另一個節點的關係。此外,你從來沒有定義變量a,所以試圖返回它會產生一個錯誤。 – InverseFalcon

+0

非常正確@InverseFalcon。這是一個例子。 WHERE,'a1'和'a2'的交互是我感興趣的。同樣,我增加了一點來提高清晰度。 –

回答

4

你看到混亂的結果的原因是因爲你假設WHERE在被RETURN抽出之前適用於整個結果。但是,情況並非如此。

從文檔上Cypher Structure

WHERE:在自己的權利不是一個條款,但比賽的一部分而是, 可選MATCH和WITH。將約束添加到某個模式,或過濾通過WITH的中間結果 。

所以,如果我把括號說明如何使用條款組合在一起,它應該是這樣的:

MATCH (e:ZOOT {id:100}) 
OPTIONAL MATCH(e)-[a1]->(X:QAZ) 

(OPTIONAL MATCH(e)-[a2]->(Y:WSX) 
WHERE a1 is not null or a2 is not null) 

RETURN e, a1, a2 

你哪裏是隻適用於該可選MATCH(即特殊可選比賽將只包括如果a1不爲空或a2不爲空),那不是你的意圖。你想將它應用到整個事情,這樣做最簡單的方法是將查詢用的,象這樣分開:

MATCH (e:ZOOT {id:100}) 
OPTIONAL MATCH(e)-[a1]->(:QAZ) 
OPTIONAL MATCH(e)-[a2]->(:WSX) 
WITH e, a1, a2 
WHERE a1 is not null or a2 is not null 
RETURN e, a1, a2 

還有,如果你不是真的要優化這個查詢有點方式對這些關係本身感興趣,並且只想知道您的ZOOT節點是否與QAZ節點或WSX節點相匹配。您可以使用EXISTS()像這樣:

MATCH (e:ZOOT {id:100}) 
WHERE EXISTS((e)-->(:QAZ)) OR EXISTS((e)-->(:WSX)) 
RETURN e 

注意,因爲你沒有提供的關係型或使用綁定到你的終端節點的X和Y變量,我假設你不感興趣的他們;我刪除了它們以避免任何人閱讀您的查詢時感到困惑。

+0

謝謝。我對這個地方的行爲有了一些回憶,但在文檔中找不到它。無論如何,我沒有想到用_with_解決它。而且_exists_比我所做的要好。 –

+0

像冠軍一樣工作。 –

1

您可以將您的查詢更改這個

比賽(E) - [R:A1 | A2] - (x)的回報E,R,X

爲WHERE子句我討厭不言自明的,但讀this :)