Zach Moshe
Zach Moshe

Reputation: 2980

How can I break my Cypher query to 2 subqueries?

I want to have a query that starts with 2 given nodes and for each of them takes the up to 5 related nodes (by relation R1) and then looks for shortestPath between those 10 nodes (5 from the 1st and 5 from the 2nd original nodes).

I can't manage to "break" my query into 2 parts, each one calculates the 5 nodes and then MATCH the path on both of them.

My query so far is:

MATCH (n1:MyNode {node_id:12345})-[:R1]-(r1:RelatedNode)
WITH r1 LIMIT 5
MATCH (n2:MyNode {node_id:98765})-[:R1]-(r2:RelatedNode)
WITH r1,r2 LIMIT 5
MATCH p=shortestPath( (r1)-[*1..10]-(r2) )
RETURN p

The problem is that the second subquery is not really separated from the first, and still carries on r1, which makes the LIMIT wrong.

I want to run the first part, then run the second part (with only r2), and only then after having r1 and r2 calculated separately, match the shortest path. Can that be done?

Thanks!

Upvotes: 1

Views: 254

Answers (1)

Stefan Armbruster
Stefan Armbruster

Reputation: 39925

Not sure if I understood your requirement correctly. I assume you want to find the shortest path in between any of the first five neighbors of n1 and n2.

I guess you have to pass through the limited result as a collection and UNWIND it later on:

MATCH (n1:MyNode {node_id:12345})-[:R1]-(r1:RelatedNode)
WITH r1 LIMIT 5
WITH collect(r1) as startNodes
MATCH (n2:MyNode {node_id:98765})-[:R1]-(r2:RelatedNode)
WITH r2, startNodes LIMIT 5
WITH collect(r2) as endNodes, startNodes
UNWIND startNodes as s UNWIND endNodes as e
MATCH p=shortestPath( (s)-[*1..10]-(e) )
RETURN p, length(p) ORDER BY length(p) ASC LIMIT 1

Be aware that the two UNWIND basically create a cross product. So you're calculated 5*5 = 25 shortest paths. Out of them we sort by length and pick the first one.

Upvotes: 1

Related Questions