当我尝试使用MATCH&WHERE排除节点时出现错误
我有下一个节点和关系:
MERGE (a1:accz {id: 1})
MERGE (a2:accz {id: 2})
MERGE (a3:accz {id: 3})
MERGE (a4:accz {id: 4})
MERGE (a5:accz {id: 5})
MERGE (i1:itemz {id: 1})
MERGE (i2:itemz {id: 2})
MERGE (i3:itemz {id: 3})
MERGE (i4:itemz {id: 4})
MERGE (a1)-[:AUTHOR]->(i1)
MERGE (a2)-[:AUTHOR]->(i2)
MERGE (a3)-[:AUTHOR]->(i1)
MERGE (a3)-[:AUTHOR]->(i3)
MERGE (a4)-[:AUTHOR]->(i4)
MERGE (a4)-[:AUTHOR]->(i5)
MERGE (a4)-[:AUTHOR]->(i5)
MERGE (a5)-[:AUTHOR]->(i2)
MERGE (a5)-[:AUTHOR]->(i5)
当我执行时(我以明确的方式包括了accz需要与之相关的项目):
MATCH (a:accz)-[:AUTHOR]->(i:itemz) WHERE ({id: i.id} IN [({id: 3}), ({id: 4})]) RETURN a
我得到了 accz 节点(3,4,5),并且还可以。但是然后我使用WHERE排除了一些节点,例如下一个查询:
MATCH (a:accz)-[:AUTHOR]->(i:itemz) WHERE ({id: i.id} IN [({id: 3}), ({id: 4})]) AND (NOT (a)-[:AUTHOR]->(:itemz {id:5})) RETURN a
但是我继续获取 accz 节点ID:5,这应该排除在外,因为acc {id:5}是(:itemz {id:5})的作者
我做错了什么?
答案 0 :(得分:1)
在您的示例中看到的奇怪行为看起来像是错误,但可以加以解释(经过仔细考虑)。归根结底,一个结论是您应该避免在MERGE
子句中使用未绑定的节点。
您的创建查询没有MERGE
子句来创建itemz
节点i5
。也就是说,缺少此子句:MERGE (i5:itemz {id: 5})
。
因此,似乎2个MERGE (a4)-[:AUTHOR]->(i5)
子句应导致创建一个新的未标记的i5
节点,该节点没有属性-但不会创建此类节点!
似乎MERGE (a5)-[:AUTHOR]->(i5)
子句应该与新的i5
建立关系-但相反,它意外地导致与i4
形成关系!< / p>
此代码段会导致奇怪的行为(我已经添加了注释以澄清):
MERGE (a4)-[:AUTHOR]->(i4) // Makes sure `(a4)-[:AUTHOR]->(i4)` relationship exists
MERGE (a4)-[:AUTHOR]->(i5) // Matches above relationship, so creates `i5` and binds it to `i4`!
MERGE (a4)-[:AUTHOR]->(i5) // Matches same relationship, so nothing is done.
因此,在执行代码段之后,i4
和i5
被绑定到同一节点。这解释了奇怪的行为。
为避免意外结果,应避免在MERGE
子句中使用未绑定的节点。
如果在创建关系之前,您的创建查询已经包含MERGE (i5:itemz {id: 5})
子句,则您的查询应该可以正常工作。第一个查询的结果将包含accz
节点3和4,第二个查询的结果将仅包含3。
顺便说一下,({id: i.id} IN [({id: 3}), ({id: 4})])
可以大大简化为i.id IN [3, 4]
。