Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-19-2019 05:33 AM
Hi,
I am new to the Neo4j community and have a question about the algo.allShortestPaths.stream algorithm.
I have modelled a warehouse graph in neo4j, in which I have the following Node types:
Nodes are connected by the relationship CONNECTS, which has a property 'distance' describing the distance between each of the connected nodes.
Rack nodes are never connected directly to each other, but always connected via an AisleLocation.
I now want to find the shortest path (weighted on 'distance') for each possible combination of a list of Rack locations. So for example, if I have a list of Rack location names ['x', 'y', 'z'] , I want to find the shortest path distances for:
'x' --> 'y'
'x' --> 'z'
'y' --> 'x'
'y' --> 'z'
'z' --> 'x'
'z' --> 'y'
I guess I need to use the algo.allShortestPaths.stream algorithm, but I couldn't find a way to tackle my problem just yet.
Thanks in advance.
Loek
Solved! Go to Solution.
11-26-2019 12:04 PM
Hi Loek,
This might help:
with ['x',"y","z"] as rackNames
unwind rackNames as rackName
match (r: Rack {name: rackName})
with collect(distinct r) as racks
unwind racks as rack1
unwind racks as rack2
with rack1, rack2 where rack1 <> rack2
CALL algo.shortestPath.stream(rack1, rack2, 'distance',{ relationshipQuery:'CONNECTS', direction:'OUTGOING'})
YIELD nodeId, cost
return algo.asNode(nodeId).name AS name, cost
Seyed
11-26-2019 12:04 PM
Hi Loek,
This might help:
with ['x',"y","z"] as rackNames
unwind rackNames as rackName
match (r: Rack {name: rackName})
with collect(distinct r) as racks
unwind racks as rack1
unwind racks as rack2
with rack1, rack2 where rack1 <> rack2
CALL algo.shortestPath.stream(rack1, rack2, 'distance',{ relationshipQuery:'CONNECTS', direction:'OUTGOING'})
YIELD nodeId, cost
return algo.asNode(nodeId).name AS name, cost
Seyed
12-02-2019 04:45 AM
Thanks Seyed, this works. I btw also found another way. With large amounts of locations, this query is actually faster:
CALL
algo.allShortestPaths.stream("distance", {{
nodeQuery:'MATCH (n) RETURN id(n) as id',
relationshipQuery:'MATCH (n)-[r]-(p) RETURN id(n) as source, id(p) as target, r.distance as weight',
graph:'cypher'}})
YIELD
sourceNodeId, targetNodeId, distance
WITH
sourceNodeId, targetNodeId, distance
WHERE
algo.isFinite(distance) = true
MATCH
(source),
(target)
WHERE
id(source) = sourceNodeId
AND source.name in $locations
AND id(target) = targetNodeId
AND target.name in $locations
WITH
source, target, distance
WHERE
source <> target
RETURN
source.name AS source,
target.name AS target,
distance
In which $locations is an array of locations.
12-02-2019 07:41 AM
No problem @lbotman
The only concern I have with your cypher is that you first find all shortest paths between all nodes, and then filter out those that are not in locations. If you have a large graph, this might actually be quite expensive.
12-02-2019 07:54 AM
I agree. I actually fixed it now by adding a filter in the nodeQuery, which works for my specific case. But indeed, the query is quite expensive in case I don't apply the filter.
All the sessions of the conference are now available online