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
我有一张由 [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