我的cypher WHERE子句没有过滤

Ton*_*nis 3 neo4j cypher

我有一个cypher查询,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

我想要的是用于生产的行既不a1或者a2被过滤掉.

然而,我的声明在所有情况下都返回行,即使是a1并且a2都是空的.

WHERE如何真正起作用?

编辑 - 添加到查询的澄清

Inv*_*con 5

您看到令人困惑的结果的原因是因为您假设WHERE在被RETURN抽出之前适用于整个结果.但事实并非如此.

Cypher Structure的文档:

WHERE:本身不是一个条款,而是MATCH,OPTIONAL 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
Run Code Online (Sandbox Code Playgroud)

你的WHERE只适用于那个可选的MATCH(如果a1不为null或a2不为null,则只包括特定的可选MATCH),这不是你的意图.您希望将它应用于整个事物,因此最简单的方法是使用WITH来分隔查询:

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
Run Code Online (Sandbox Code Playgroud)

如果您对关系本身并不感兴趣,可以稍微优化此查询,并且只想知道您的:ZOOT节点是否与QAZ节点或WSX节点匹配.您可以像这样使用EXISTS():

MATCH (e:ZOOT {id:100})
WHERE EXISTS((e)-->(:QAZ)) OR EXISTS((e)-->(:WSX))
RETURN e
Run Code Online (Sandbox Code Playgroud)

请注意,由于您没有提供关系类型或使用绑定到末端节点的X和Y变量,我假设您对它们不感兴趣; 我删除了它们以避免任何阅读您查询的人产生混淆.