Kiran Kulkarni
Kiran Kulkarni

Reputation: 1504

Inherit property of parent node for current node in cypher - neo4j

I have run into a problem where I have my graph constructed something like this :

          A
        /   \
       B     C
     /  \   /  \
    D    E  F   G

All my nodes are of type Object:i.e, Match (n:Object) And I have created this graph with only one relation (parent and child) i.e, (A)-[:child]->(B) , (A)-[:child]->(C) , (B)-[r:child]->D , etc till node G

I have a property defined at each node called: levelID Some of the nodes might not have this levelID. The nodes which do not have levelID should inherit that from its parent node.

Now, when I run the cypher (assuming C and G does not have levelID) :

MATCH (n1:Object)-[:child]->(n2:Object) 
return n2.id as id,
CASE
WHEN n2.levelId is null
THEN n1.levelId    //I am stuck here. (what if node C has levelID as null)
ELSE n2.levelId
END AS level

This is not giving the desired output.

Expected: (consider C and G has levelId= null)

id  node       level
1    A           1
2    B           2
3    C           1
4    D           4
5    E           5
6    F           6
7    G           1

But, this is my actual :(

id  node       level
1    A           1
2    B           2
3    C           1
4    D           4
5    E           5
6    F           6
7    G           null

Upvotes: 0

Views: 916

Answers (1)

stdob--
stdob--

Reputation: 29147

Find root node, take path from root to node, and find in this path the first node with the desired property:

// Find root
MATCH (root:Object) WHERE NOT (:Object)-[:child]->(root) WITH root

// Loop through nodes
MATCH (n:Object) WITH n, root

// The path from the root to the node
MATCH path = (root)-[:child*0..]->(n)

WITH n, 
     // An array of properties (including those which are null)
     EXTRACT(node IN NODES(path) | node.levelId) AS levelIdsForTest

WITH n,
     // Filter the ones that are not null
     FILTER(level IN levelIdsForTest WHERE level IS NOT NULL) AS levelIds

RETURN n.id           AS id,
       n.levelId      AS selfId,
       // Take the last one - it is the nearest
       LAST(levelIds) AS inheritId

Upvotes: 2

Related Questions