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

Check previously visited nodes on 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 的节点有连接,这会导致比需要的检查更多。

如何在访问一个节点之前检查它是否已经被访问过?有可能吗?

老实说,我不知道 cypher 是否执行 DFS - 你也不应该知道或关心。

cypher 的一大优势是它是一种声明式图形查询语言。也就是说,你告诉它你想要什么数据,它就会去获取它。您不必知道或关心如何,并且希望随着时间的推移,查询优化器变得更好,它最终会比您更快地完成它。将此与命令式图形查询进行对比,在命令式图形查询中,您可以指定如何获取数据。

Cypher 通常不会回溯它已经结束的路径,因为那样效率不高,但它可能会根据查询多次访问某些节点(即,如果有多个路径通过同一节点)。

Cypher 不提供任何功能来控制图形遍历的发生方式 - 希望您同意我的看法,这是一个功能,而不是错误。

如果你想细粒度地控制图的遍历方式,看到了什么,或者遇到事情要做什么,那么我想你想要the java Traversal API。在许多其他选项中,您可以指定 BFS/DFS,并且可以指定遍历选项,例如 "only visit each node once"(无论指定什么关系)或翻转 "only visit each relationship once".

现在,对于您的特定查询,如果它返回的路径比您想要的多得多,您可能需要缩小查询范围以删除不需要的路径。例如,您可能想查看 longest path queries 以摆脱层次结构中的 "shortcut" 路径。

您还可以在 Cypher 中使用 shortestPath(),这是一种优化的双向算法。 (或allShortestPaths())

以你的例子为例:

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

确保 :Industry(id)

有一个 index/constraint