我有一个不符合预期的cypher查询,我试图找出原因。我怀疑我不完全理解OPTIONAL MATCH
的工作原理。
数据库有一个(:'Person::Current')
节点和一个(:'Trait::Current')
节点。它没有(:'PersonTrait::Current')
节点。
如果我运行此查询,则会正确返回{1}} 1
count(t)
将MATCH (n:`Person::Current` {uuid: $person_id}), (t:`Trait::Current` {uuid: $trait_id})
WHERE NOT (
(n)-[:PERSON_TRAIT]->(:`PersonTrait::Current` {has: true})-[:PERSON_TRAIT]->(t) OR
(n)-[:PERSON_TRAIT]->(:`PersonTrait::Current` {has: false})-[:PERSON_TRAIT]->(t) OR
(t)-[:GIVES_TRAIT]->(:`GivesTrait::Current`)-[:GIVES_TRAIT]->(:`Trait::Current`)<-[:PERSON_TRAIT]-(:`PersonTrait::Current` {has: false})<-[:PERSON_TRAIT]-(n)
)
RETURN count(t) as res
节点以
(:'PersonTrait::Current')
我的查询正确返回计数(t)为0。
但是,如果我尝试使用(:`Person::Current`)-[:PERSON_TRAIT]->(:`PersonTrait::Current` {has: true})-[:PERSON_TRAIT]->(:`Trait::Current`)
来干扰查询,就像这样
OPTIONAL MATCH
当MATCH (n:`Person::Current` {uuid: $person_id}), (t:`Trait::Current` {uuid: $trait_id})
OPTIONAL MATCH (pt:`PersonTrait::Current`)
WHERE NOT (
((n)-[:PERSON_TRAIT]->(pt)-[:PERSON_TRAIT]->(t) AND exists(pt.has)) OR
(t)-[:GIVES_TRAIT]->(:`GivesTrait::Current`)-[:GIVES_TRAIT]->(:`Trait::Current`)<-[:PERSON_TRAIT]-(pt {has: false})<-[:PERSON_TRAIT]-(n)
)
RETURN count(t) as res
节点以
(:'PersonTrait::Current')
任何人都知道出了什么问题?如果(:`Person::Current`)-[:PERSON_TRAIT]->(:`PersonTrait::Current` {has: true})-[:PERSON_TRAIT]->(:`Trait::Current`)
节点存在适当的模式,WHERE NOT
子句应该过滤掉(t)
个节点。
感谢!!!
答案 0 :(得分:1)
我认为问题在于理解WHERE子句,因为WHERE仅适用于前一个MATCH,OPTIONAL MATCH或WITH子句。
在这种情况下,它与OPTIONAL MATCH配对,因此当WHERE为false时,行将不会被过滤掉,它的行为与OPTIONAL MATCH失败时的行为相同,因此新引入的变量在OPTIONAL MATCH中将被设置为null。
如果希望WHERE过滤掉行,请将其与WITH子句配对:
MATCH (n:`Person::Current` {uuid: $person_id}), (t:`Trait::Current` {uuid: $trait_id})
OPTIONAL MATCH (pt:`PersonTrait::Current`)
WITH n, t, pt
WHERE NOT (
((n)-[:PERSON_TRAIT]->(pt)-[:PERSON_TRAIT]->(t) AND exists(pt.has)) OR
(t)-[:GIVES_TRAIT]->(:`GivesTrait::Current`)-[:GIVES_TRAIT]->(:`Trait::Current`)<-[:PERSON_TRAIT]-(pt {has: false})<-[:PERSON_TRAIT]-(n)
)
RETURN count(t) as res