I have a graph of Airports, Routes between them and Airlines that carry it. I created routes as separate nodes, rather than just a relationship, so that I can connect each with an Airline, and other nodes.
Each Route
node has an IS_FROM
relationship with the origin airport and an IS_TO
relationship with the destination. It also has an IS_BY
relationship with its airline:
I am trying to traverse this tree, n
times, for routes between two airports. For example, if n = 3
, I want to get all the routes, that will lead from LAX
to LHR
, with 3 or fewer connections.
So basically, my result would be a union of the following: No Connecting Airports:
MATCH (a1:Airport {iata : 'LAX'})<-[:IS_FROM]-(r:Route)-[:IS_TO]->(a2:Airport {iata : 'LHR'}), (r)-[:IS_BY]->(ai:Airline) return a1 , r , a2 , ai;
1 Connecting airports:
MATCH (a1:Airport {iata : 'LAX'})<-[:IS_FROM]-(r:Route)-[:IS_TO]->(a2:Airport)<-[IS_FROM]-(r2:Route)-[:IS_TO]->(a3:Airport {iata: 'LHR'}), (r2)-[:IS_BY]->(ai:Airline) return a1 , r , a2 , a3 , r2 , ai;
and so on.
So the query should dynamically traverse the (:Airport)<-[:IS_FROM]-(:Route)-[:IS_TO]->(:Airport)
pattern n times, and return the nodes (I am more interested in returning the Airline
s that connect to those routes.
You can first extract all the paths between Airports that are 3 or less hops away, and then use OPTIONAL MATCH
to see which of the nodes in the path are Routes, and which Airlines are offering them.
MATCH path = (:Airport {iata:$start_airport})-[*2..6]-(:Airport {iata:$end_airport})
WITH path,nodes(path) as path_airports_and_connecting_routes
UNWIND path_airports_and_connecting_routes as node
OPTIONAL MATCH (node)-[:IS_BY]-(airline:Airline)
WITH collect(node) as airports_and_routes,airline
RETURN airports_and_routes + [airline]
Caveat: Variable-length paths don't allow passing parameters, so you can't do something like [*2..2*n]
.