Neo4J - Cypher: shortest path between multiple nodes

情到浓时终转凉″ 提交于 2019-12-13 04:15:32

问题


Let's say we have 4 nodes:

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

Suppose node 1 is linked to node 2, node 2 to 3, 3 to 4 so the result would be something like:

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

How would I be able to get the shortest path between multiple given nodes in any given order? A few examples:

findShortestPath(2,4,3) should result in: (2)-->(3)-->(4)

findShortestPath(3,1) should result in: (1)-->(2)-->(3)

findShortestPath(4,1) should result in: (1)-->(2)-->(3)-->(4)

findShortestPath(3,2) should result in: (2)-->(3)

I have tried something like this, but I feel like I'm going the wrong way and it's not the most performant solution. Note that my query gets constructed programmatically since it can contain any number and kind of nodes.

If the input would be: (2),(3),(1)

That would result in a double for loop constructing something like this:

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;

My problem is that I can't provide multiple nodes to the allShortestPaths() function. Only 2 nodes with 1 relation is allowed.


回答1:


You can go through all the pairs of nodes, and check that the other nodes are in the possible paths between these pairs:

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


来源:https://stackoverflow.com/questions/51444694/neo4j-cypher-shortest-path-between-multiple-nodes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!