Neo4J-Cypher:多个节点之间的最短路径

时间:2018-07-20 14:23:51

标签: neo4j cypher

假设我们有4个节点:

{id:1, name:"one"} {id:2, name:"two"} {id:3, name:"three"} {id:4, name:"four"}

假设节点1链接到节点2,节点2链接到3,3到4,则结果将类似于:

(1)-->(2)-->(3)-->(4)

如何以任何给定顺序获得多个给定节点之间的最短路径?几个例子:

findShortestPath(2,4,3)应该导致:(2)-->(3)-->(4)

findShortestPath(3,1)应该导致:(1)-->(2)-->(3)

findShortestPath(4,1)应该导致:(1)-->(2)-->(3)-->(4)

findShortestPath(3,2)应该导致:(2)-->(3)

我已经尝试过类似的方法,但是我觉得我走错了方向,这并不是最有效的解决方案。请注意,我的查询是通过程序构造的,因为它可以包含任意数量和种类的节点。

如果输入为:(2),(3),(1)

这将导致double for循环构造如下内容:

match p=allShortestPaths((p2)-[*]-(p3)),allShortestPaths((p2)-[*]-(p1)),allShortestPaths((p3)-[*]-(p1)) where p1.name="Keanu Reeves" and p2.name="Gene Hackman" and p3.name="Clint Eastwood" return p;

我的问题是我无法为allShortestPaths()函数提供多个节点。只允许2个具有1个关系的节点。

1 个答案:

答案 0 :(得分:1)

您可以遍历所有节点对,并检查其他节点是否在这些对之间的可能路径中:

WITH ["Keanu Reeves", "Gene Hackman", "Clint Eastwood"] AS names
UNWIND names AS nn
  MATCH (n {name: nn})
  WITH collect(n) AS nds

UNWIND nds AS n1
  UNWIND nds AS n2
  WITH nds, n1, n2 WHERE id(n1) > id(n2)
    MATCH path = allShortestPaths((n1)-[*]-(n2))
    WITH nds, path WHERE ALL(n IN nds WHERE n IN nodes(path))
RETURN path ORDER BY length(path) ASC