cancel
Showing results for 
Search instead for 
Did you mean: 

Find last leaf cypher?

MPasadu
Node Link

Hey,

what's the best way to find the last leaf node? It's for a timeline like structure where a node is added at the end.
Schema looks like this: (:Node)<-[:IS_PARENT]-(:Node)<-[:IS_PARENT]-(:Node).......

So a Node will always only have one parent.

I could maybe match the number of relations and if it's only 1 then I know it is the last leaf.
Or I could save an additional property isLastLeaf = true just so I can match it. But then I have to change the property every time I add a new leaf. Or maybe get the :Node with the highest id?

What is the recommended approach?

1 ACCEPTED SOLUTION

You can use a path predicate (along with NOT) to add a pattern restriction involving nodes in your MATCH pattern.

For example, if you wanted a pattern that encompassed a path from the root to a leaf, you could use:

MATCH (root:Node)<-[:IS_PARENT*]-(leaf:Node)
WHERE NOT ()<-[:IS_PARENT]-(root) AND NOT (leaf)<-[:IS_PARENT]-()
...

A root has no outgoing :IS_PARENT relationship (it has no parent), and a leaf has no incoming :IS_PARENT relationship (it has no children).

Under the hood, since the patterns used here are only concerned about relationships on our matched nodes (note that we don't have any info, not even label, on the node at the other end of the relationship), then there's no need to actually expand the relationship...the planner knows it can just check the degree of :IS_PARENT relationships for the given direction on the node itself, which is fairly efficient.

View solution in original post

2 REPLIES 2

12kunal34
Graph Fellow

Please find below query for your question

for find root node that doesn't have any parent

MATCH (root)
WHERE NOT ()-->(root) AND size((root)-->()) > 1
return root

for find leaf node

MATCH (root)
WHERE NOT ()<--(root) AND size((root)<--()) > 1
return root

You can use a path predicate (along with NOT) to add a pattern restriction involving nodes in your MATCH pattern.

For example, if you wanted a pattern that encompassed a path from the root to a leaf, you could use:

MATCH (root:Node)<-[:IS_PARENT*]-(leaf:Node)
WHERE NOT ()<-[:IS_PARENT]-(root) AND NOT (leaf)<-[:IS_PARENT]-()
...

A root has no outgoing :IS_PARENT relationship (it has no parent), and a leaf has no incoming :IS_PARENT relationship (it has no children).

Under the hood, since the patterns used here are only concerned about relationships on our matched nodes (note that we don't have any info, not even label, on the node at the other end of the relationship), then there's no need to actually expand the relationship...the planner knows it can just check the degree of :IS_PARENT relationships for the given direction on the node itself, which is fairly efficient.

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

On November 16 and 17 for 24 hours across all timezones, you’ll learn about best practices for beginners and experts alike.