我有一个大数据集,我正在进行以下查询以查找两个节点之间的路径:
MATCH (a:Industry{ id:140 }),(b:Industry{ id:386 })
WITH a,b
MATCH p=(a)-[:SELLS*..3]->(b)
return p
我听说cypher会做DFS,这对我来说没问题。但是我的图有很多循环,所以在很多情况下,例如(树)级别3的节点与级别1的节点有连接,这导致检查的次数远远超过需要。
如何在访问节点之前检查节点是否已被访问过?它甚至可能吗?
答案 0 :(得分:0)
老实说,我不知道密码是否会执行DFS - 您也不应该知道或关心。
cypher的一大优势是它是一种声明式图形查询语言。也就是说,你告诉它你想要什么数据,然后就可以获得它。您不必知道或关心如何,并希望随着时间的推移,查询优化器会变得更好,它最终会比您可能更快地完成它。将此与命令式图形查询进行对比,您可以在此指定如何获取数据。
Cypher通常不会回溯它已经结束的路径,因为这样做效率不高,但它可能会多次访问某些节点,具体取决于查询(即,如果有多条路径通过同一节点)。
Cypher没有提供任何控制图遍历发生的功能 - 希望你能同意我这是一个功能,而不是一个bug。
如果您希望对遍历图表的方式,已经看到的内容或遇到事情时该怎么做进行细粒度控制,那么我认为您需要the java Traversal API。在许多其他选项中,您可以指定BFS / DFS,并且可以指定遍历选项,例如“仅访问每个节点一次”(无论关系指定的是什么)或翻转,“仅访问每个关系一次”。
现在,对于您的特定查询,如果它返回的路径比您想要的多得多,也许您需要缩小查询范围以摆脱您不想要的路径。例如,您可能希望查看longest path queries以消除层次结构中的“快捷方式”路径。
答案 1 :(得分:0)
您也可以在Cypher中使用shortestPath()
,这是一种优化的双向算法。 (或allShortestPaths()
)
对于你的例子:
MATCH (a:Industry{ id:140 }),(b:Industry{ id:386 })
MATCH p=shortestPath((a)-[:SELLS*..3]->(b))
return p
确保您拥有:Industry(id)