我有一个类似的密码查询:
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
我想要的是不会过滤掉a1
或a2
的行。
然而,我的陈述是在所有情况下都返回行,即使a1
和a2
都是空的。
WHERE如何真正起作用?
编辑 - 添加到查询的澄清
答案 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)