简体   繁体   中英

Neo4j: How can I write this query better?

I am new in Neo4j. I tried to do this query:

"Mati Gol would like to watch a new movie. therefore would like to get the following list of movies: Write a query that returns all movies that were LIKED by any person who is a FRIEND of the person with the name Mati Gol or is a FRIEND of a FRIEND of Mati Gol, excluding all movies WATCHED by Mati Gol."

My query is:

MATCH (a:person {name:"Moti Gol"})-[:WATCHED]->(b)
WITH collect(b) AS Already_Watched
MATCH (a:person {name:"Moti Gol"})-[:FRIEND*1..2]->(b)-[:LIKED]->(c) 
WITH collect(c) AS Friend_Liked
(movie:Friend_Liked) WHERE NOT (movie.name) IN Already_Watched 
RETURN movie.name

Is this query OK? Can someone offer me better writing of this?

Your query has some errors... Firstly, the first line has no MATCH statement. You are MATCHing (a:person {name:"Moti Gol"}) two times and redeclaring the a variable.

A more simple and intuitive way to do the same query:

// get all the movies liked by friends or friends of friends of "Moti Gol"...
MATCH (a:person {name:"Moti Gol"})-[:FRIEND*1..2]->(b:person)-[:LIKED]->(c:movie)
// excluding all movies WATCHED by Mati Gol
WHERE NOT (a)-[:WATCHED]->(c)
// return the movies
RETURN c.name

Here is a solution which I think is what you were after from the start but didn't quite get right.

// find the person and the movies they have already watched
MATCH (a:Person {name:"Mati Gol"})-[:WATCHED]->(movie:Movie)
WITH a, collect(movie) as my_movie_list

// find the person's friends and the movies that they like
MATCH (a)-[:FRIEND*1..2]->(:Person)-[:LIKED]->(movie:Movie)
WITH a, my_movie_list, collect(DISTINCT movie) as friend_movie_list

// return the friend like movies that are not already watched
RETURN [m IN friend_movie_list WHERE NOT m in my_movie_list] as movies_to_watch

I think this solution gives you a little more cost certainty as it should only traverse the movie nodes once each. If there is a lot of duplication in movies LIKED by friends and friends of friends (which I expect is a reasonably likely scenario) then reducing the list of LIKED movies to the distinct list first and then filtering it against the movies watched afterwards could save on database comparisons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM