Search code examples
neo4jcypher

Recursively find all parent nodes for a given node in neo4j


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"}.

enter image description here

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.


Solution

  • [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.)