0
votes

I'm working with Flight Analyzer database (https://neo4j.com/graphgist/flight-analyzer). We have there few nodes and relationships types. Nodes: Airport

(SEA:Airport { name:'SEA' })

Flight

(f0:Flight { date:'11/30/2015 04:24:12', duration:218, distance:1721, airline:'19977' })

Ticket

(t1f0:Ticket { class:'economy', price:1344.75 })

Relationships Destination

(f0)-[:DESTINATION]->(ORD)

Origin

(f0)-[:ORIGIN]->(SEA)

Assign

(t1f0)-[:ASSIGN]->(f0)

Now I need to find some path and I have problem with that connection ORIGIN - FLIGHT - DESTINATION. I need to find all airports that are connected to LAX airport with sum of ticket prices < 3000.

I tried

MATCH path = (origin:Airport { name:"LAX" })<-[r:ORIGIN|DESTINATION*..5]->(destination:Airport)
WHERE REDUCE(s = 0, n IN [x IN NODES(path) WHERE 'Flight' IN LABELS(x)] |
s + [(n)<-[:ASSIGN]-(ticket) | ticket.price][0]
) < 3000
RETURN path

but in this solution LAX can be ORIGIN and DESTINATION too. I only want to chose paths that always have the same order aiport1 <- origin - flight1 - destination -> airport2 <- origin - flight2 - destination -> aiport etc..

I need to include departure and arrive time so flight1 date + duration < flight2 date then flight2 date + duration < flight3 date etc...

1

1 Answers

0
votes

[UPDATED]

This query should check that:

  • matched paths have alternating ORIGIN/DESTINATION relationships, and
  • every departing flight lands at least 30 minutes before the next departing flight (if any), and
  • the sum of the ticket prices of the Flight nodes (which are every other node starting at the second one) < 3000
MATCH p = (origin:Airport {name: 'LAX'})-[:ORIGIN|DESTINATION*..5]-(destination:Airport)
WHERE
  ALL(i IN RANGE(0, LENGTH(p)-1) WHERE
    TYPE(RELATIONSHIPS(p)[i]) = ['ORIGIN', 'DESTINATION'][i] AND
    (i%4 <> 1 OR (i + 2) > LENGTH(p) OR
      (apoc.date.parse(NODES(p)[i].date,'m','MM/dd/yyyy hh:mm:ss') + NODES(p)[i].duration + 30) < apoc.date.parse(NODES(p)[i+2].date,'m','MM/dd/yyyy hh:mm:ss'))
  ) AND
  REDUCE(s = 0, n IN [k IN RANGE(1, LENGTH(p), 2) | NODES(p)[k]] |
    s + [(n)<-[:ASSIGN]-(ticket) | ticket.price][0]
  ) < 3000
RETURN p

The query uses the apoc.date.parse function to convert each date into the number of epoch minutes, so that a duration (assumed to also be in minutes) can be added to it.