Reputation: 1504
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
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