cancel
Showing results forΒ
Did you mean:Β

Head's Up! Site maintenance this Wednesday, February 1. Disruptions expected as we migrate the forums.

## Find last leaf cypher?

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
Neo4j

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.

2 REPLIES 2
Graph Fellow

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
``````
Neo4j

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 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online

Neo4j Resources