f7n
f7n

Reputation: 1674

Matching multiple relationships in Cypher?

I'm trying to form a query that matches against multiple relationships. Here is my query torn down to the basics:

START inputMovie=node(1)
MATCH inputMovie<-[r:RATED]-User-[o:RATED]->(movies)<-[:IS_GENRE]->genres
RETURN movies.title LIMIT 5

I want it to return a list of movies that have been rated the same person, and are of the same genre. What am I doing wrong?

thank you

Upvotes: 3

Views: 6556

Answers (1)

cybersam
cybersam

Reputation: 66957

You have a typo, as Cypher does not allow bidirectional relationships: <-[:IS_GENRE]->.

Taking a guess at your data model, this might work for you:

START inputMovie=node(1)
MATCH inputMovie<-[r:RATED]-User-[o:RATED]->(movies)-[:IS_GENRE]->genres
RETURN movies.title LIMIT 5;

Note: the above query can return duplicate results, since multiple users can watch the same movies. If this is a concern, you can use the DISTINCT qualifier to prevent that. For example:

START inputMovie=node(1)
MATCH inputMovie<-[r:RATED]-User-[o:RATED]->(movies)-[:IS_GENRE]->genres
RETURN DISTINCT movies.title LIMIT 5;

[EDITED]

If you want to return only movies that have (at least) all of the same genres as the inputMovie, you can do the following.

START inputMovie=node(1)
MATCH (inputGenre)<-[:IS_GENRE]-(inputMovie)
WITH inputMovie, COLLECT(inputGenre) AS inputGenres
MATCH (inputMovie)<-[r:RATED]-(User)-[o:RATED]->(movie)-[:IS_GENRE]->(genre)
WITH inputGenres, movie, COLLECT(genre) AS genres
WHERE ALL(x IN inputGenres WHERE x IN genres)
RETURN movie.title LIMIT 5;

Notes:

  • I have renamed a couple of identifiers, for clarity (i.e., movies and genres).
  • The DISTINCT qualifier is no longer needed, as aggregation over the movie node (in the second WITH clause) implicitly makes each movie instance unique.

Upvotes: 3

Related Questions