Reputation: 4058
I have this relationship in my neo4j:
Parent -> Childs
F -> D,E
D -> A,B,C
A -> X
Use case: I am trying to get all child of a particular node using this query till a particular depth let's say depth
= 2
Query to get All child of node F
MATCH (p:Person)-[:REPORTS_TO *]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]-(c)
RETURN p,c;
This returns me this: (which is all child's node of F without limit)
But when I try to get all childs till depth 2 :
Query to get All child of node F
with depth = 2
MATCH (p:Person)-[:REPORTS_TO *2]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]->(c)
RETURN p,c;
Which returns
When I put depth = 2, it didn't return all child's of D' (only returned A and not
B`, 'C')
Expected response was:
All child's of 'F', child's of all child's of `F' (i.e level 1) and child's of all childs of nodes of level 1 (i.e level 2)
Am I missing something in my query or any another way to get a response as I expected above?
Adding dataset
CREATE (f:Person {name: "F"})
CREATE (e:Person {name: "E"})
CREATE (d:Person {name: "D"})
CREATE (c:Person {name: "C"})
CREATE (b:Person {name: "B"})
CREATE (a:Person {name: "A"})
CREATE (x:Person {name: "X"})
CREATE (a)-[:REPORTS_TO]->(x)
CREATE (d)-[:REPORTS_TO]->(a)
CREATE (d)-[:REPORTS_TO]->(b)
CREATE (d)-[:REPORTS_TO]->(c)
CREATE (f)-[:REPORTS_TO]->(d)
CREATE (f)-[:REPORTS_TO]->(e)
Upvotes: 1
Views: 636
Reputation: 30397
The problem is you're not querying for what you think you're querying for.
[:REPORTS_TO *2]
doesn't query up to depth 2, it queries nodes at exactly depth 2. The result is nodes B, C, A, and F (since you added it in).
Of those nodes, only nodes A and F have an outgoing :REPORTS_TO relationship, so your match eliminates B and C from the result set. The nodes returned are A and F and the nodes reachable by an outgoing :REPORTS_TO relationship (E, D, and X).
If you want to alter your query so it's up to depth 2 instead of exactly depth 2, use a range on the variable-length relationship (omitting the lower-bound makes it default to 1):
[:REPORTS_TO *..2]
And if you want this to include F in the match itself (instead of manually adding it when you collect the nodes), use a lower bound of 0:
[:REPORTS_TO *0..2]
Upvotes: 2