【问题标题】:Neo4J - Cypher: shortest path between multiple nodesNeo4J - Cypher:多个节点之间的最短路径
【发布时间】:2018-07-20 14:23:50
【问题描述】:

假设我们有 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)

这将导致双重 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() 函数提供多个节点。仅允许具有 1 个关系的 2 个节点。

【问题讨论】:

    标签: neo4j cypher


    【解决方案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
    

    【讨论】:

    • 哦,对了,这看起来很有趣。我偶然发现了 Neo4J 网站上的双重放松。但是,WHERE ALL (bla IN bla) 部分似乎是我正在寻找的。谢谢!
    • 最后,感谢您的解决方案,我能够解决它。我不得不对其进行一些更改,因为我使用节点的 ID 而不是 name 属性。
    • 我有一个问题,我的节点可能是不同类型的。如果我将它用作第一行WITH ["Keanu Reeves", "The Matrix", "Clint Eastwood"] AS names,那么我会收到 3 个节点,但即使 Keanu Reeves 与它有关系(ACTED_IN),矩阵节点也不在图中。我希望从黑客帝国到基努·里维斯以及从基努到克林特·伊斯特伍德的节点。你能解释为什么这没有出现吗?我很高兴得到与使用 Hackman 相同的结果。
    • 问题是电影类型节点没有name属性,但是有title属性。所以你需要这个改变:... MATCH (n) WHERE n.name = nn OR n.title = nn ...
    • 或者像这样:... MATCH (n) WHERE ANY(k IN keys(n) WHERE n[k] = nn) ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2023-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多