ehftwelve
ehftwelve

Reputation: 3137

match property on nodes in path of cypher shortestPath

For simplicity sake, let's say I have a graph like this (using actors/movies as an example):

Nodes:

Actor(id:1)
Actor(id:2)
Actor(id:3)
Movie(id:4,rating:'PG-13')
Movie(id:5,rating:'PG-13')

Relationships:

Actor(id:1) APPEARS_IN Movie(id:4)
Actor(id:2) APPEARS_IN Movie(id:4)
Actor(id:2) APPEARS_IN Movie(id:5)
Actor(id:3) APPEARS_IN Movie(id:5)

Cypher to create the sample graph:

create (a1:Actor {id: 1, name: 'Actor 1'})
create (a2:Actor {id: 2, name: 'Actor 2'})
create (a3:Actor {id: 3, name: 'Actor 3'})
create (m1:Movie {id: 4, rating:'PG-13', name: 'Movie 1' } )
create (m2:Movie {id: 5, rating:'PG-13', name: 'Movie 2' } )
create (a1)-[:APPEARS_IN]->(m1)
create (a2)-[:APPEARS_IN]->(m1)
create (a2)-[:APPEARS_IN]->(m2)
create (a3)-[:APPEARS_IN]->(m2)
return *

So now we have want to find the shortest path between Actor(id:1) and Actor(id:3). That's easy enough, we might try a cypher query like:

MATCH p=shortestPath((a:Actor { id: 1 })-[:APPEARS_IN*0..14]-(b:Actor { id: 3 })) RETURN NODES(p)

And we would get a result.

This is where my question comes in How can I put a requirement on the nodes in between (specifically the movie nodes) to only include rating:'R' as part of its path?

Upvotes: 1

Views: 380

Answers (1)

Dave Bennett
Dave Bennett

Reputation: 11216

This query will only return the nodes of the shortest path between the two actors where all of the movies are R rated.

It filters out the Movie nodes and then checks to make sure that the rating of each movie node in the collection is R.

MATCH p=shortestPath((a:Actor { id: 1 })-[:APPEARS_IN*0..14]-(b:Actor { id: 3 })) 
WHERE all ( movie in filter( m in nodes(p) where 'Movie' in labels(m)) where movie.rating = 'R')
RETURN nodes(p)

Upvotes: 1

Related Questions