0
votes

I would like to query a shortestpath in Neo4j but expressing conditions between consecutive relations.

Suppose I have nodes labelled type and relations labelled rel. Such relations have the attributes start_time, end_time, exec_time (for the moment they are of type string, but if you prefer you can consider them as integer). I would like to find the shortest path between two nodes b1 and b2 subject to the constraint that:

  • the relation outgoing from b1 should have the attribute starting_time bigger than a given value (let me call it th;
  • if there are more than one of such relations, starting_time of the next relation should be bigger than ending_time of the previous.

Between two nodes I can have multiple realations.

I started from this query limiting the relations with starting_time bigger than th.

MATCH (b1:type{id:"0247"}), (b2:type{id:"0222"}), 
p=shortestPath((b1)−[t:rel*]−>(b2))
WHERE ALL (r in relationships(p) WHERE r.starting_time>"14:56:00" )
RETURN p;

I was trying something like this:

MATCH (b1:type{id:"0247"}), (b2:type{id:"0222"}), 
p=shortestPath((b1)−[t:rel*]−>(b2))
WITH "14:56:00" as th
WHERE ALL (r in relationships(p) WHERE r.starting_tme>th WITH r.end_time as th )
RETURN p;

but it does not work and I am not sure the shortestPath algorithm in Neo4j accesses the relations of the shortest path sequentially.

How can I express such a condition in Neo4j cypher query language?

If it is not possible is there a suitable way to model such a time condition in a graph database (I mean how can I change the DB?)

1

1 Answers

1
votes

This query may do what you want:

MATCH p = shortestPath((b1:type{id:"0247"})−[t:rel*]−>(b2:type{id:"0222"}))
WHERE REDUCE(s = {ok: true, last: "14:56:00"}, r IN RELATIONSHIPS(p) |
  {ok: s.ok AND r.starting_time > s.last, last: r.end_time}
  ).ok
RETURN p;

This query uses REDUCE to iteratively test the relationships while updating the current state s at every step.