cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! Site migration is underway. Phase 2: migrate recent content

Length pattern. Find nodes at a certain distance from another node

Hello,

I'm a newbe in Neo4j.

I've a graph which looks like this (:Person) - [:VISITS] -> (:Location). I'd like to find people at a distance of maximum 3 "visits" from a given Person

eg: Paul -VISITED-> New-York <-VISITED- Frank -VISITED-> Paris <-VISITED- Mike.
Paul is at 1 "visit/distance" from Frank and 2 "visits/distance" from Mike

I've tried

MATCH path = (person:Person)-[:VISITS*2..6]-(other:Person)
WHERE apoc.coll.duplicates(NODES(path)) = [] AND person.name = "Paul" 
RETURN person.name, other.name 

([:VISITS*2..6] because a distance of 1 => 2 relationships "VISITS")

Does my query seem correct ? Because it takes a lot of time to give result (never give any result except if I decrease the distance eg: [:VISITS*2..4])

1 ACCEPTED SOLUTION

Bennu
Graph Fellow

Hi @triumph.demontae !

If you are alread open to APOC, just go:

MATCH (person:Person)
WHERE  person.name = "Paul" 
WITH person
CALL apoc.path.subgraphNodes(person , {
   minLevel : 2,
   maxLevel: 6,
   relationshipFilter : "VISITS"
})
yield node
where node:Person
with person, node as other
RETURN person.name, other.name 

Bennu

View solution in original post

3 REPLIES 3

Bennu
Graph Fellow

Hi @triumph.demontae !

If you are alread open to APOC, just go:

MATCH (person:Person)
WHERE  person.name = "Paul" 
WITH person
CALL apoc.path.subgraphNodes(person , {
   minLevel : 2,
   maxLevel: 6,
   relationshipFilter : "VISITS"
})
yield node
where node:Person
with person, node as other
RETURN person.name, other.name 

Bennu

Thank you for your answer, it seems to work greatly !

Out of curiosity, is it possible to achieve it with (I mean without APOC)

(person:Person)-[:VISITS*2..6]-(other:Person)

Hi @triumph.demontae !

Yes, but it's not as performant an APOC version because you will be removing duplicates after you already calculate all the paths. In this use case, I wouldn't care too much about it and just filter distinct at the end.
Maybe:

MATCH (person:Person)
WHERE  person.name = "Paul" 
WITH person
MATCH path = (person)-[:VISITS*2..6]-(:Person)
WITH person, [n in nodes(path) where n:Person] as ns
UNWIND ns as other
RETURN distinct person.name, other.name

Bennu