1
votes

Working with Neo4J moovie graph, when I execute this query:

match (p:Person)-[ai:ACTED_IN]->(m:Movie)
where not (p.name in ['Keanu Reeves'])
return m limit 1

I am getting movies where Keanu Reeves acted in like 'The Matrix Revolutions'. I assumed that the query should return movies in which Keanu Reeves did not act. What am I doing wrong? What is the proper way to get the movies where Keanu did not act?

2
Multiple people act in a single movie (...generally), and you're counting over actors-in-movies. You want to count over movies, filtering for those where none of the actors are Keanu Reeves.jonrsharpe

2 Answers

2
votes

The Patrick Bösch answer works, but it is building a cartesian product between (p:Person) and (m:Movie) nodes.

The below query will do the same job, but avoiding cartesian products (and in a more clear way, I think):

MATCH (m:Movie)
WHERE NOT (m)<-[:ACTED_IN]-(:Person {name : 'Keanu Reeves'})
RETURN m

The query will MATCH all movies avoiding ones that have a relation :ACTED_IN with a :Person node that name is equal to Keanu Reeves.

UPDATE

From comments:

What if it is not just Keanu Reeves but keanu Reeves AND Robin Williams?

Then you can do:

MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WITH m, collect(p) as actors
WHERE NONE (actor in actors WHERE actor.name IN ['Keanu Reeves', 'Robin Williams'])
RETURN m

Or:

MATCH (m:Movie)
WHERE NONE(n in ['Keanu Reeves', 'Robin Williams']
    WHERE (m)<-[:ACTED_IN]-(:Person {name:n}))
RETURN m
1
votes

If you like to get all movies where Keanu Reeves doesn't acted in you have to exclude this relationship from the result otherwise you will get the movies where Keanu Reeves and any other of the actors acted in too.

Get all movies where Keanu Reeves didn't acted in:

MATCH (p:Person),(m:Movie)
WHERE p.name IN ['Keanu Reeves']
AND NOT ((p)-[:ACTED_IN]->(m))
RETURN m