问题描述
MATCH (n:Person)-[k:KNowS]->(f)
WHERE k.since < 2000
RETURN f.name,f.age,f.email
直接来自于 neo4j 示例。
我想做的是: 按名称从一个节点(在本例中为“Jennifer”)开始,并找到所有节点,无论路径深度如何,这些节点源自初始节点但关系 KNowS 自 所以詹妮弗可能在 2000 年之前就认识加里,而在 2000 年之前就认识比尔。詹妮弗在 2000 年之前就认识了米歇尔(et cetera)
这就是我被卡住的地方:
MATCH p=(n:Person {name:'Jennifer'})-[:KNowS*]-(f)
RETURN [k IN p WHERE k.since < 2000]
如果我使用 :KNowS* 运行任何查询,它只会永远挂起,即使对于 21 个节点和 840 个关系的相对较小的数据库也是如此。
我想我需要以某种方式使用 WITH REDUCE() 但它没有点击...
有人能指出我正确的方向吗? 非常感谢!
解决方法
您可以使用 all()
列表谓词来确保路径中的所有关系都遵循该谓词。这将在扩展期间进行评估,因此可能会产生更好的性能:
MATCH p=(n:Person {name:'Jennifer'})-[:KNOWS*]-(f)
WHERE all(rel in relationships(p) WHERE rel.since < 2000)
RETURN DISTINCT f
也就是说,Cypher 关注的是找到适合该模式的所有可能路径,当您对不同的节点而不是不同的路径感兴趣时,这种方法并不总是很好的匹配(尤其是当路径回溯到之前访问过的路径时)节点通过不同的关系)。
您可能需要考虑为可变长度扩展添加一个上限。