组合Cypher中的集合的意外行为

时间:2016-10-05 12:26:28

标签: neo4j cypher

使用http://console.neo4j.org作为沙箱,我遇到了以下意外行为:

声明1 - 返回包含Neo Node

的集合的1行
MATCH (n:Crew) 
WHERE n.name="Neo" 
WITH COLLECT(n) AS c1
WITH c1+[] AS c2
RETURN c2

声明2 - 返回0行(意外)

MATCH (n:Crew) 
WHERE n.name="Neo" 
WITH COLLECT(n) AS c1
MATCH (n:Crew) 
WHERE n.name="NoOne"
WITH c1+COLLECT(n) AS c2
RETURN c2

声明3 - 返回包含空集合的1行

MATCH (n:Crew) 
WHERE n.name="NoOne"
WITH COLLECT(n) AS c1
RETURN c1

我不明白为什么语句2 没有返回与语句1 相同的结果,因为它应该返回包含Neo节点的集合,就像在声明1 。
声明3 表明声明2 中的第二个MATCH应该会产生一个空集合。

Cypher期待这种行为吗?如果是这样的话,我会很乐意帮助我理解这种行为。

2 个答案:

答案 0 :(得分:5)

我之前遇到过这种确切的行为,这非常令人沮丧。问题在于查询2中的第二个MATCH子句:如果现有结果行(在这种情况下,您的单行包含c1)未返回MATCH的任何结果,该行将在MATCH子句之后完全删除,即使 MATCH自己(没有预先存在的结果行)返回空集合。如果您将其转换为OPTIONAL MATCH,则可以在没有匹配项时保留结果行。

更新:请参阅下面的更全面的分析,但是tl,dr是语句2 中的第二个COLLECT(n) 返回一个空列表,就像在Statement 3中一样;但是,整个子句WITH c1+COLLECT(n) AS c2不返回任何行,因为在第二个c1之后没有行MATCH的行。

答案 1 :(得分:1)

我无法想到为什么第二个查询没有达到预期效果的正确解释,但是如果你想要连接多个可选匹配,那么你可以使用一个可选的匹配做到这一点:

OPTIONAL MATCH (n:Crew) 
WHERE n.name="Neo" 
WITH COLLECT(n) AS c1
OPTIONAL MATCH (n:Crew) 
WHERE n.name="NoOne"
WITH c1+COLLECT(n) AS c2
RETURN c2