在Neo4j中,图中有4个人节点; 2与电影节点有关系,其他2没有关系。
期望下面的查询只返回2个没有关系的节点,但它返回all。
如果查询中遗漏了任何内容,请告诉我。我是Neo4J的新手
MATCH (p:Person)
OPTIONAL MATCH (p) -[r]- (m:Movie)
Where type(r) = null
Return p,type(r),m
谢谢!
答案 0 :(得分:1)
您获得意外结果的原因是由于WHERE子句的位置和含义,以及它与OPTIONAL MATCH行为的相互作用。
WHERE仅适用于前面的MATCH,OPTIONAL MATCH或WITH。在这种情况下,它不适用于查询的所有结果,它仅适用于OPTIONAL MATCH,并且这与您期望的行为完全不同。
如果您将其隔离并查看OPTIONAL MATCH和WHERE,它会有所帮助:
OPTIONAL MATCH (p) -[r]- (m:Movie)
Where type(r) = null
这意味着:可选地从p匹配到:电影m到关系r,其中r为空。你不能拥有一个存在的关系,但它的类型是null,这是不可能的,所以这个可选的MATCH总会失败。
但是因为它是一个可选的MATCH,所以不会删除行,而是非匹配的元素将为null。结果是行:Person p(来自您之前的匹配),null为类型(r)和m。
您实际想要的是首先执行可选匹配,然后过滤掉类型为null的行。你想要一个影响查询所有行的WHERE,而不是OPTIONAL MATCH。
这要求我们添加一个WITH子句,并在其后移动WHERE:
MATCH (p:Person)
OPTIONAL MATCH (p) -[r]- (m:Movie)
WITH p, r, m
Where type(r) = null
Return p, type(r), m
将WHERE从OPTIONAL MATCH移动到WITH更改其含义,它现在将应用于查询的所有行,并且因为它不再与可选MATCH相关联,它实际上会删除不适合的行谓词,而不是保持行和设置元素为空。
现在,所有这一切,有一个更容易的查询返回你想要的东西而不使用OPTIONAL MATCH:
MATCH (p:Person)
WHERE NOT (p)--(:Movie)
RETURN p
匹配:与那些没有关系的人员节点:人员到:电影节点。
我们可以省略返回关系类型和电影节点,因为那些根据你的匹配不存在。