Rémi Chaffard
Rémi Chaffard

Reputation: 87

Neo4j cypher how to stop recursivity at first match

Considering a graph like this:

START -> A -> B -> C {attr: X} -> D {attr: X}

I would like to retrieve the paths from START to first item where attr is 'X'

I tried to search a bit and modifying queries I found, but no luck. Doing this will return 2 paths:

MATCH p=(START)-[*1..]->(n:node {attr:X}) RETURN p

I tried this but no luck:

MATCH p=(START)-[*1..]->(n:node {attr:X}) 
WHERE SINGLE(x in nodes(p) WHERE x.attr = X) 
RETURN P

But this still returns 2 paths.

How can I get only the path I want ?

Another way to see it could be to get only the longest path (stopping at D node). If I am sure D is a leaf, how can I get only the path stopping at the leaf ? In this last case it will retrieve the longest one but only one.

Thanks a lot Rémi

EDIT

In fact to be more precise, I do not want only the shortest or the longest path between 2 nodes, so LIMIT is not a solution. I want either:

One real example can be this, START is the brown node at the bottom and nodes having attr:X are the 2 yellow ones at top.

graph_example

In this example, we have 8 paths between START and nodes having attr:X. I want to have only 4, either stoping at the first yellow node, or stoping at the last, but never both.

Thanks

Upvotes: 2

Views: 590

Answers (2)

Rémi Chaffard
Rémi Chaffard

Reputation: 87

OK I found my mistakes and finally make it working.

Thanks a lot cybersam for your help.

My solution is:

  1. For the paths stopping at first occurence:

Usage of single

MATCH p = (START)-[*]->(n:node {attr:X})
WHERE SINGLE (n IN NODES(p) WHERE EXISTS(n.attr) AND n.attr = X)
RETURN p

I noticed for this one that SINGLE (n IN NODES(p) WHERE n.attr = X) does not work, since attr does not exists in all nodes along the path.

  1. For the paths stopping at leaf:

Solution given by cybersam works perfectly

MATCH p = (START)-[*]->(n:node {attr:X})
WHERE NOT (n)-->()
RETURN p

Rémi

Upvotes: 1

cybersam
cybersam

Reputation: 67019

These examples might be helpful.

To find a single shortest path to the first node with X (which I assume is defined earlier in the query):

MATCH p = (START)-[*]->(n:node {attr:X})
WHERE NOT ANY (n IN NODES(p)[..-1] WHERE 'node' IN LABELS(n) AND n.attr = X)
RETURN p
ORDER BY LENGTH(p)
LIMIT 1

To find a single shortest path to a leaf node with X:

MATCH p = (START)-[*]->(n:node {attr:X})
WHERE NOT (n)-->()
RETURN p
ORDER BY LENGTH(p)
LIMIT 1

Upvotes: 3

Related Questions