Search code examples
neo4jcypher

Neo4j find shortest distance (stored in properties)


I have a travel database in Neo4j that looks like this:

(Airport)-[Starts]-(Flight)-[Arrives]-(Airport)

Properties: Airport:name, Flight:distance.

The way I find the shortest path currently is:

MATCH p = shortestPath(({name:'Airport1'})-[*]->({name:'Airport2'}))
RETURN nodes(p) limit 1

With this query I can find the least amount of nodes needed to connect Airport1 to Airport2. Since multiple *-[Starts]-(Flight)-[Arrives]-(Airport)-* can be between the starting point and the target airport. Is there a simpler way to calculate the minimum distance (sum of flight.distance) than hardcoding the number of transfers in the query?

Technically 3 transfers can be less distance than 2 in the following case: EU-EU-EU-EU airports in the EU travell or EU-US-EU (One is travelling only in Europe the other is going to US and back)

Tried summarize the distance found by shortestPath, which is usually the correct answer but there are outliers.

Hardcoded in the query the number of transfers.


Solution

  • If you simplified your data model to this:

    (:Airport {name: 'ORD'})-[:FLIGHT {id: 'DL404', distance: 1234}]->(:Airport {name: 'LAX'})
    

    Then you can use the APOC function apoc.algo.dijkstra to find the "weighted shortest path" using distance as the weight:

    MATCH (from:Airport {name: 'ORD'}), (to: Airport {name: 'SFO'})
    CALL apoc.algo.dijkstra(from, to, 'FLIGHT', 'distance') YIELD path, weight
    RETURN path, weight