可选匹配和WHERE无法一起正常工作

时间:2019-06-09 18:23:17

标签: neo4j cypher

执行以下查询:

MATCH (p: Post)-[r]->(reply: Post) 
OPTIONAL MATCH (profile:Profile)-[r2:Likes]->(reply) 
WHERE p.key = $postKey
RETURN reply, collect(profile.key) 

目的是将所有回复返回给定帖子,并告诉喜欢的人(如果有人喜欢)。第二个匹配项是可选的,因为您仍应返回所有不喜欢的答复。取而代之的是所有答复期。以下查询确实有效:

MATCH (p: Post {key:$postKey})-[r]->(reply: Post) 
OPTIONAL MATCH (profile:Profile)-[r2:Likes]->(reply)  
RETURN reply, collect(profile.key)

现在,我在某种程度上理解了Cypher查询,这些查询是顺序执行的,不进行处理,然后整体执行。因此,在第二个示例中,它仅获取对给定帖子的答复,然后获得喜欢的消息,然后返回,而在第一个示例中,它首先获取所有答复,然后获取所有的喜欢消息,然后应过滤它们。我的问题如下:

  1. 为什么不过滤它们?我假设可选匹配导致Post不再在数据集中,因此过滤器被忽略。

  2. 是否有一种方法可以在何处使用而不会发生这种情况?

  3. 最后考虑到这确实可以带回家,您应该使用顺序查找还是应该出于性能原因而避免在哪里进行查找?

1 个答案:

答案 0 :(得分:0)

这种误解的根源是WHERE不是独立的子句,它修改了以前的MATCH,OPTIONAL MATCH或WITH子句。

将它们作为一对阅读...

MATCH ... WHERE ...

WITH ... WHERE ...

OPTIONAL MATCH ... WHERE ...

OPTIONAL MATCH的行为是不会过滤掉任何结果。相反,如果OPTIONAL MATCH失败(包括其配对的WHERE子句的结果),则OPTIONAL MATCH模式中新引入的变量将返回null。

因此,使用该信息,您可以看到WHERE子句实际上位于错误的位置。它与OPTIONAL MATCH相关联,而应改为遵循MATCH,从而限制了这些结果(如果在:Post(key)上具有索引,则可以进行索引查找。)

您可以用来解决的另一种方法(在这种情况下不正确,但在其他情况下有用)是在OPTIONAL MATCH后面加上WITH ... WHERE ...,这将允许WHERE子句过滤出结果。

one of our Neo4j knowledge base articles中的更多信息。