Neo4j Cypher 对 WHERE 变量 "may" 以不同模式出现的单一查询

Neo4j Cypher Single Query to WHERE variables "may" appear in different patterns

我有一张由 [IS_A] 关联的 parent-children objects 的图表,它们可能相互关联 [HAS]:

假设属性由 children 继承。我想创建一个可以回答所有问题的查询:
牌桌有底座吗? - (l {name:'card table'})-[:IS_A*]->(m)-[:HAS]->(n)-[:IS_A*]-> (o {姓名:'base'})
牌桌有腿吗? - (l {name:'card table'})-[:IS_A*]->(m)-[:HAS]->(o {name:'leg'})
家具有底座吗? - (l {name:'furniture'})-[:HAS]->(n)-[:IS_A*]->(o {name:'base'})
家具有腿吗? - (l {name:'furniture'})-[:HAS]->(o {name:'leg'})

不知道我的 objects 将匹配什么模式我想在一个查询中同时测试它们。 这是对我有意义但不起作用的查询:

MATCH (l {name:'X'}), (m), (n), (o {name:'Y'})
WHERE (l)-[:IS_A*]->(m)-[:HAS]->(n)-[:IS_A*]->(o) OR (l)-[:IS_A*]->(m)-[:HAS]->(o) OR (l)-[:HAS]->(n)-[:IS_A*]->(o) OR (l)-[:HAS]->(o)
RETURN l, m, n, o

Where 的工作一一进行。但是我得到了数据库中的每个节点和关系!

哦,伙计,我是个笨蛋,我应该只 RETURN l, o
如果我 return m, n 和 m, n 不是查询的子项,那么我是在间接请求所有内容。

所以正确的查询是: MATCH (l {name:'X'}), (m), (n), (o {name:'Y'})
其中 (l)-[:IS_A*]->(m)-[:HAS]->(n)-[:IS_A*]->(o) 或 (l)-[ :IS_A*]->(m)-[:HAS]->(o) 或 (l)-[:HAS]->(n)-[:IS_A*]->( o) 或 (l)-[:HAS]->(o)
RETURN l, o

如果我得到任何节点 returned 答案是 YES 否则 NO

更好的方法可能是为特征找到所有后代,并为这些后代找到所有拥有者。这些将是具有该特征的事物的集合:

 (characteristic)<-[:IS_A*0..]-(descendent)<-[:HAS]-(possessor)

您可以聚合这些(或使用模式理解,以便它们已经在列表中)

现在,对于您给定的待测物品,您所要做的就是查看它是否有任何祖先在拥有者列表中。

我们可以使用 LIMIT 1 来加快速度,因为我们只需要在找到第一个匹配项时停止。

MATCH (characteristic:Thing {name:$characteristic}), (thing:Thing {name:$thing})

WITH characteristic, thing, 
 [(characteristic)<-[:IS_A*0..]-(descendent)<-[:HAS]-(possessor) | possessor] as possessors

MATCH path = (thing)-[:IS_A*0..]->(ancestor)
WHERE ancestor IN possessors
RETURN ancestor
LIMIT 1