当尝试查找具有唯一节点出现的所有路径时,Cypher查询失败并且具有可变长度路径

时间:2017-10-23 14:53:21

标签: neo4j cypher

我有一个高度互联的图表,从特定节点开始 我想找到连接到它的所有节点,无论关系类型,方向或长度如何。我想要做的是过滤出包含节点超过1次的路径。但我得到的是

Neo.DatabaseError.General.UnknownError: key not found: UNNAMED27

我设法创建了一个更简单的数据库 在neo4j沙箱中,使用以下数据再次获取相同的消息:

CREATE (n1:Person { pid:1, name: 'User1'}), 
       (n2:Person { pid:2, name: 'User2'}),
       (n3:Person { pid:3, name: 'User3'}), 
       (n4:Person { pid:4, name: 'User4'}),
       (n5:Person { pid:5, name: 'User5'})

具有以下关系:

MATCH (n1{pid:1}),(n2{pid:2}),(n3{pid:3}),(n4{pid:4}),(n5{pid:5})
CREATE (n1)-[r1:RELATION]->(n2), 
       (n5)-[r2:RELATION]->(n2), 
       (n1)-[r3:RELATION]->(n3), 
       (n4)-[r4:RELATION]->(n3)

在上述模型中导致此问题的Cypher查询是

MATCH p= (n:Person{pid:1})-[*0..]-(m) 
WHERE ALL(c IN nodes(p) WHERE 1=size(filter(d in nodes(p) where c.pid = d.pid)) ) 
return  m

有人可以看到这个查询有什么问题吗?

2 个答案:

答案 0 :(得分:2)

错误对我来说似乎是个错误。有closed neo4j issue似乎相似,但它应该在版本3.2.1中修复。您可能应该为它创建一个新问题,因为您的评论声明您正在使用3.2.5。

同时,此查询应该得到您想要的结果:

MATCH p=(:Person{pid:1})-[*0..]-(m)
WITH m, NODES(p) AS ns
UNWIND ns AS n
WITH m, ns, COUNT(DISTINCT n) AS cns
WHERE SIZE(ns) = cns
return m

但是,您应该强烈考虑在可变长度路径搜索上设置合理的上限。如果您不这样做,那么在任何合理的数据库大小的情况下,您的查询可能需要非常很长时间和/或内存不足。

答案 1 :(得分:0)

在查找路径时,Cypher永远不会在单个路径中两次访问同一节点。因此MATCH (a:Start)-[*]-(b) RETURN DISTINCT b将返回连接到a的所有节点。 (这里的DISTINCT是多余的,但它会影响查询性能。在你的Neo4j版本上使用PROFILE来查看它是否关心,哪个更好)

注意:这适用于Neo4j 3.2 Cypher规划器。对于以前的版本  Cypher规划器,唯一有效的方法是使用APOC,或者从起始节点向所有子节点添加-[:connected_to]->关系,以便不必探索路径。)