Reputation: 1559
I want to write a cypher query where given a node X, it gives all the parent nodes for that given node until I find the root node which has the type attribute as ROOT.
As an example, I have attached below image where my RootNode is the main parent node and it has attribute {type: "ROOT"}.
Example1: Find all parent nodes for a node with label TYPE2:X3 From the graph we can see, TYPE2:X3 has one parent nodes TYPE2:X1. Now TYPE2:X1 has two parents TYPE1:T1 and RootNode. Recursively, finding parent of TYPE1:T1 which is RootNode. Hence, the answer will be TYPE1:T1 and TYPE2:X1
Example2: Find all parent nodes for a node with label TYPE2:X4 From the graph we can see, TYPE2:X4 has 4 parent nodes TYPE1:T1, TYPE2:X1, TYPE2:X2, TYPE1:T2 who all have parent as RootNode so the answer will be these 4 nodes.
Please note that my graph can have upto 10 level of parent nodes like this.
Upvotes: 0
Views: 458
Reputation: 67044
[UPDATED]
This query will return all distinct ancestor
nodes by following all outbound relationships starting at a given n
node, excluding any node that has no outbound relationships.
... // (prior Cypher providing n)
MATCH p = (n)-[*..8]->(root)
WHERE NOT EXISTS((root)-->())
UNWIND NODES(p)[1..-1] AS ancestor
RETURN DISTINCT ancestor
This query also puts an upper bound on the variable length pattern to avoid taking forever or running out of memory.
The x[1..-1]
syntax specifies a sublist of x
consisting of its second element up to and including its next-to-last element. (The documentation is a bit misleading, as it concentrates on the range()
function, whereas specifying a sublist does not depend on using the range()
function at all. The 2 concepts should have been covered separately.)
Upvotes: 0
Reputation: 655
The simplest thing to do is just traverse the graph with variable path length:
match path = (s)-[*..9]->()-->(e)
where s:X4 and s:TYPE2 and e:ROOT
with [n in nodes(path) where n <> e | n] as parentnodes
return parentnodes
Variable path length can make the query explode, especially if you have supernodes. If you have a fairly balanced tree structure like in your diagram, this may be okay.
UPDATE: This will make it so you don't need to know the label on the root node:
match path = (s)-[*..9]->()-->(e)
where s:X4 and S:TYPE2 and not (e)->()
with [n in nodes(path) where n <> e | n] as parentnodes
return parentnodes
Upvotes: 0