0
votes

I am trying to obtain the node and edge ids for the shortest path between two nodes in my neo4j graph database.

If I do not specify which nodes I want, the code runs somehow and returns a path:

import py2neo

graph.run("MATCH (start:Point)-[:SOURCE_POINT]->(r:Road)-[:TARGET_POINT]->(end:Point) \
CALL apoc.algo.dijkstraWithDefaultWeight(start, end, 'Road', 'length', 10.0) \
YIELD path as path, weight as weight \
UNWIND nodes(path) as n \
RETURN DISTINCT { id : id(n), labels : labels(n), data: n} as node").to_table()

But when I run the same code and specify which nodes I want, it returns empty:

graph.run("MATCH (start:Point {id: '4984061949'})-[:SOURCE_POINT]->(r:Road)-[:TARGET_POINT]->(end:Point {id: '4984061963'}) \
...

If I simply try to match those node id's, it returns them ok - so I know they are in the db.

I'm thinking it could be because my 'cost' is a string. But I'm not sure how to cast it to float before it goes through the dijkstraWithDefaultWeight function.

1

1 Answers

1
votes

You seem to have a couple of issues.

1. MATCH clause is too restrictive

  • The following MATCH clause would only succeed if there was a path between the specified start and end nodes consisting of just one Road:

    MATCH (start:Point {id: '4984061949'})-[:SOURCE_POINT]->(r:Road)-[:TARGET_POINT]->(end:Point {id: '4984061963'})
    

    If that MATCH clause fails, then your query would return nothing.

  • The following MATCH clause would succeed if there was a path between any pair of Point nodes consisting of one Road:

    MATCH (start:Point)-[:SOURCE_POINT]->(r:Road)-[:TARGET_POINT]->(end:Point)
    

    If that MATCH clause succeeds, then, of course, the Dijkstra procedure will also succeed.

  • Instead of either of the above, you should probably just use MATCH to get the two endpoints and let the Dijkstra algorithm do the job of finding the path:

    MATCH (start:Point {id: '4984061949'}), (end:Point {id: '4984061963'})
    

2. Wrong procedure argument(s)

The third argument passed to apoc.algo.dijkstraWithDefaultWeight is supposed to specify relationship types and directions, not node labels. Also, the last 2 arguments are supposed to be a relationship property and default relationship property value, respectively.