简单匹配查询需要很长时间

时间:2019-01-04 15:30:38

标签: neo4j cypher

我有一个简单的查询

MATCH (n:TYPE {id:123})<-[:CONNECTION*]<-(m:TYPE) RETURN m

,并且在“手动”执行查询时(即使用浏览器界面跟踪边沿),由于没有更多连接,因此我只能得到一个节点。通过查询进行确认

MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:TYPE)<-[n:CONNECTION]-(o:TYPE) RETURN m,o

未显示结果,并且

MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:TYPE) RETURN m

显示一个节点,因此我没有犯错手动进行查询。

但是,问题是第一个问题要花很多时间才能解决,我不明白为什么。

因此即使最大结果为1,这种琐碎的查询仍要花这么长时间的原因是什么?

奖金如何解决此问题?

2 个答案:

答案 0 :(得分:2)

正如Tezra所述,可变长度模式匹配与您列出的其他两个查询不在同一类别中,因为在nm之间的任何节点上都没有限制,它们可以是任何类型。假设您的查询花费了很长时间,那么您可能会在不同类型的节点之间拥有相当密集的:CONNECTION关系图。

如果要确保路径中的所有节点都具有相同的标签,则需要自己添加:

MATCH path = (n:TYPE {id:123})<-[:CONNECTION*]-(m:TYPE) 
WHERE all(node in nodes(path) WHERE node:TYPE)
RETURN m

或者,您可以使用APOC过程,它具有一种相当有效的方法来查找连接的节点(并通过标签限制路径中的节点):

MATCH (n:TYPE {id:123})
CALL apoc.path.subgraphNodes(n, {labelFilter:'TYPE', relationshipFilter:'<CONNECTION'}) YIELD node
RETURN node
SKIP 1 // to avoid returning `n`

答案 1 :(得分:1)

MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:TYPE)<-[n:CONNECTION]-(o:TYPE) RETURN m,o不是对MATCH (n:TYPE {id:123})<-[:CONNECTION*]<-(m:TYPE) RETURN m的公正测试,因为它排除了MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:ANYTHING_ELSE)<-[n:CONNECTION]-(o:TYPE) RETURN m,o的可能性。

对于主要查询,您应该返回DISTINCT结果MATCH (n:TYPE {id:123})<-[:CONNECTION*]<-(m:TYPE) RETURN DISTINCT m

这主要有两个原因。

  • 没有区别,每个节点需要返回到它的每个可能路径的次数。
  • 由于前一点,这是很多额外的工作,没有其他有意义的信息。

如果使用RETURN DISTINCT,则密码规划器可以选择进行修剪搜索而不是详尽搜索。

您还可以使用..#来限制穷举搜索的深度,以便在使用Cypher Planner尚未学习修剪搜索的较旧版本的Neo4j时,它也不会杀死您的查询。示例使用MATCH (n:TYPE {id:123})<-[:CONNECTION*..10]<-(m:TYPE) RETURN m