Returning only simple paths in Neo4j Cypher query
Asked Answered
L

3

15

Given a query like the following:

START n = node(123)
MATCH p = n-[r:LIKES*..3]->x
RETURN p;

The result paths that I get with the query above contain cycles.

How can I return only simple paths?

Given this example:

  • How can I avoid paths with repeated nodes like: [Neo, Morpheus, Trinity, Morpheus, Neo]
Lalo answered 7/12, 2012 at 17:9 Comment(3)
Note that the path length 3 is a query parameter thet can changeLalo
Do you have an example using console.neo4j.org/usage.html?Intercommunicate
@PeterNeubauer just added one!Lalo
B
16

Specifying the uniqueness of paths is a planned feature of cypher.

So right now we have to ascertain that no node is a duplicate in the path.

There is an ALL predicate that must hold true for all elements of a collection (which a path is). And with filter you can extract the elements of an collection for that a certain condition holds true.

START neo=node(1) 
MATCH path= neo-[r:KNOWS*..4]->other 
WHERE ALL(n in nodes(path) where 
          1=length(filter(m in nodes(path) : m=n))) 
RETURN neo, LENGTH(path) AS length, EXTRACT(p in NODES(path) : p.name), other 
ORDER BY length

So what I did was:

  • For all nodes of the path n
  • Filter the path for the nodes that are equal to n
  • determine the length of that collection
  • assert with ALL that it has to be ONE for each n

see: http://console.neo4j.org/r/dpalbl

Babettebabeuf answered 19/12, 2012 at 9:15 Comment(4)
Hi Michael, Is there any other better way to identify cycles in path. The solution shared above by you, works fine but, is costly in terms of time & db hits. Can u please check?Onionskin
While working with Neo4j 2.2.5 I had to change the filter part to filter(m in nodes(path) WHERE m=n))Posthaste
Hi. Does anyone know of any updates on this in the 3.0 release?Chowchow
For graph:create (n:ent {id:'a'})-[:rel]->(:ent {id:'b'})-[:rel]->(o:ent {id:'c'})-[:rel]->(p:ent {id:'d'})-[:rel]->(:ent {id:'e'})-[:rel]->(n),(p)-[:rel]->(o), the query MATCH path=(ent{id:'a'})-[:rel*0..]->(ent) WHERE ALL(n in nodes(path) WHERE 1=length(filter(m in nodes(path)WHERE m=n))) RETURN path gives key not found: UNNAMED25 error!!!Peccary
F
3

my workaround for this:

START n = node(123), x=node(*)
MATCH p = shortestPath(n-[r:LIKES*..3]->x)
RETURN p;

see the example in console

Farming answered 14/12, 2012 at 13:9 Comment(1)
This might work in the given example but I'm actually interested in all possible paths (not only the shortest one/s) within a given length with no nodes repeated along the way. thanksLalo
W
2

In 2.3.0, use the following:

MATCH path = (start {id:2})<-[*1..]-(end {id:3}) 
WHERE ALL(n in nodes(path) where 
          1 = size(filter(m in nodes(path) where m=n))) 
RETURN start, LENGTH(path) AS length, EXTRACT(p in NODES(path) | p.id), end
ORDER BY length
Wept answered 3/11, 2015 at 1:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.