我的cypher WHERE子句没有过滤

时间:2016-07-21 21:57:22

标签: neo4j 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

我想要的是不会过滤掉a1a2的行。

然而,我的陈述是在所有情况下都返回行,即使a1a2都是空的。

WHERE如何真正起作用?

编辑 - 添加到查询的澄清

2 个答案:

答案 0 :(得分:5)

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

来自Cypher Structure的文档:

  

地点:本身不是一个条款,而是MATCH的一部分,   可选的比赛和与。向模式添加约束或过滤   中间结果通过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

您的WHERE仅适用于该可选比赛(如果a1不为null或a2不为空,则仅包含特定的可选比赛),这不是您的意图。您希望将它应用于整个事物,因此最简单的方法是使用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

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

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

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

答案 1 :(得分:2)

您可以将查询更改为此

  

匹配(e) - [r:a1 | a2] - (x)返回e,r,x

对于WHERE子句,我讨厌陈述明显但只读this:)