jab
jab

Reputation: 5823

Cypher Get Valid Trip

Let's say that I have a graph that holds trips as relationships in neo4j, each relationship has a start time and end time, and I need to find a valid path from node1 to node2. I need to find this path that adheres to the constraints of relationship1.arrivetime < relationship2.departime.

Is there a way to include this functionality within a MATCH clause, or will I have to filer existing paths I find with a WHERE clause?

Upvotes: 0

Views: 76

Answers (2)

Eve Freeman
Eve Freeman

Reputation: 33155

As peter said, in order to inspect properties, you need to use the where clause. The match patterns are for pattern matching without inspecting properties. You can, however, use indexes to find nodes to start at that fit a certain range of time, for example.

I built an example for you:

create 
(_1 {city:"DC"}), 
(_2 {city:"NY"}), 
(_3 {city:"SF"}),
(_4 {city:"LA"}), 
_1-[:flight {leave:1349431200, arrive:1349445600}]->_2,
_1-[:flight {leave:1349427600, arrive:1349442000}]->_2,
_1-[:flight {leave:1349424000, arrive:1349438400}]->_2,
_1-[:flight {leave:1349420400, arrive:1349434800}]->_2,
_1-[:flight {leave:1349416800, arrive:1349431200}]->_2,
_1-[:flight {leave:1349409600, arrive:1349424000}]->_2,
_2-[:flight {leave:1349431200, arrive:1349445600}]->_3,
_2-[:flight {leave:1349427600, arrive:1349442000}]->_3,
_2-[:flight {leave:1349424000, arrive:1349438400}]->_3,
_3-[:flight {leave:1349431200, arrive:1349445600}]->_4,
_3-[:flight {leave:1349427600, arrive:1349442000}]->_4,
_3-[:flight {leave:1349424000, arrive:1349438400}]->_4,
_3-[:flight {leave:1349438400, arrive:1349445600}]->_4,
_3-[:flight {leave:1349442000, arrive:1349449200}]->_4,
_3-[:flight {leave:1349445600, arrive:1349452800}]->_4;

Just for fun, here's a query that shows all of the flights that match the destinations (before filtering): http://console.neo4j.org/r/6ropic There need to be negative time differences all across in order to be a valid trip.

Here's a query with the where clause filtering:

start dc=node(1), la=node(4)  
match trip=dc-[dcny]->ny-[nysf]->sf-[sfla]->la  
where dcny.arrive < nysf.leave and nysf.arrive < sfla.leave  
return dcny.arrive - nysf.leave, nysf.arrive - sfla.leave, dcny.arrive, nysf.leave, nysf.arrive, sfla.leave;
+-----------------------------------------------------------------------------------------------------------+
| dcny.arrive - nysf.leave | nysf.arrive - sfla.leave | dcny.arrive | nysf.leave | nysf.arrive | sfla.leave |
+-----------------------------------------------------------------------------------------------------------+
| -3600.0                  | -3600.0                  | 1349424000  | 1349427600 | 1349442000  | 1349445600 |
+-----------------------------------------------------------------------------------------------------------+
1 row
0 ms

http://console.neo4j.org/r/79qr9s

It's a bit trickier if you want to try to do it with variable length paths, but for this use case it's probably not the end of the world to specify a few layovers at most.

Update:

Was thinking about this some more--you could also select a group of relationships in your start clause, based on an index for the arrive and leave times. Would limit your search a lot.

Upvotes: 1

Peter Neubauer
Peter Neubauer

Reputation: 6331

You use the where clause for filtering on the relationship properties. If you need fine grained control of the traversal, you can also use the Traverser Java API, see http://docs.neo4j.org/chunked/snapshot/tutorials-java-embedded-traversal.html

Upvotes: 2

Related Questions