检查以前在cypher上访问过的节点

时间:2015-01-27 13:53:51

标签: database performance neo4j cypher

我有一个大数据集,我正在进行以下查询以查找两个节点之间的路径:

MATCH (a:Industry{ id:140 }),(b:Industry{ id:386 })
WITH a,b
MATCH p=(a)-[:SELLS*..3]->(b)
return p

我听说cypher会做DFS,这对我来说没问题。但是我的图有很多循环,所以在很多情况下,例如(树)级别3的节点与级别1的节点有连接,这导致检查的次数远远超过需要。

如何在访问节点之前检查节点是否已被访问过?它甚至可能吗?

2 个答案:

答案 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)

的索引/约束