spanishgum
spanishgum

Reputation: 1052

How can I use LIMIT on specific nodes in a path in CYPHER?

Let's say I have this query:

enter image description here

How can I use LIMIT on different layers of this path? It seems to only affect the last node in a path.

What if I wanted say 1 Year, 3 Months, and then 5 days for each of the months?

How about with a conditional on corresponding months? i.e. if M=2, get D=[1,2,3,4,5], if M=3, D=[11,12,13,14,15])?

Something like this:

enter image description here

As of now I have been manually editing these diagrams by expanding, deleting, expanind, etc. It is quite tedious, so I'm hoping there is a way to do this in the query.

I've tried a few things like mulitple returns with separate limits, unions, but I can't seem to make anything work.

I would like to do this in the browser. I believe that means it must be a single command.

I've been trying things like:

MATCH (t:TimeTreeRoot)-[c1:CHILD]-(y:Year) 
WITH t, c1, y LIMIT 1 
MATCH (t)-[c1]-(y)-[c2:CHILD]-(m:Month) 
WITH t, c1, y, c2, m LIMIT 3 
MATCH (m)-[c3:CHILD]-(d:Day) 
WITH t, c1, y, c2, m, c3, d 
MATCH p=(t)-[c1]-(y)-[c2]-(m)-[c2]-(d) 
RETURN p LIMIT N

But the behaviour is inconsistent. It seems as though a preceding LIMIT is negated by a following one.

Upvotes: 1

Views: 1487

Answers (1)

InverseFalcon
InverseFalcon

Reputation: 30407

I'm not sure you can do all this in a single match and capture it as a path. At this time LIMIT applies to the entire result set. If Neo4j adds subqueries in the future, then you can use it there in the way you intend.

You can get a similar result set of nodes in a different way though, by collecting nodes and getting the relevant slice, and if you want to, unwind the collection into rows afterward.

MATCH (t:TimeTreeRoot)-[:CHILD]->(y:Year)-[:CHILD]->(m:Month)
WITH t, y, m LIMIT 3
MATCH (m)-[:CHILD]->(d:Day)
WITH t, y, m, COLLECT(d)[0..5] as days
UNWIND days as d
RETURN t, y, m, d

Alternately, since you're working with TimeTree and have the value properties to work with, you could use those to select the exact days you want (provided they have been created).

MATCH (t:TimeTreeRoot)-[:CHILD]->(y:Year)-[:CHILD]->(m:Month)
WITH t, y, m LIMIT 3
MATCH (m)-[:CHILD]->(d:Day)
WHERE d.value in RANGE(1,5)
RETURN t, y, m, d

You can add to your WHERE clause to get different days per month.

MATCH (t:TimeTreeRoot)-[:CHILD]->(y:Year)-[:CHILD]->(m:Month)
WITH t, y, m LIMIT 3
MATCH (m)-[:CHILD]->(d:Day)
WHERE (m.value = 3 AND d.value in RANGE(11,15)) OR (m.value <> 3 AND d.value in RANGE(1,5))
RETURN t, y, m, d

Upvotes: 2

Related Questions