执行以下查询:
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查询,这些查询是顺序执行的,不进行处理,然后整体执行。因此,在第二个示例中,它仅获取对给定帖子的答复,然后获得喜欢的消息,然后返回,而在第一个示例中,它首先获取所有答复,然后获取所有的喜欢消息,然后应过滤它们。我的问题如下:
为什么不过滤它们?我假设可选匹配导致Post不再在数据集中,因此过滤器被忽略。
是否有一种方法可以在何处使用而不会发生这种情况?
最后考虑到这确实可以带回家,您应该使用顺序查找还是应该出于性能原因而避免在哪里进行查找?
答案 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子句过滤出结果。