我是Neo4j的新手。我试图做这个查询:
" Mati Gol想看一部新电影。因此,我想获得以下电影列表:编写一个查询,返回所有电影,这些电影是任何名为Mati Gol的朋友的朋友,或者是Mati Gol的朋友的朋友,不包括所有电影由Mati Gol观看。"
我的查询是:
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
这个查询好吗?有人能给我更好的写作吗?
答案 0 :(得分:3)
您的查询有一些错误......首先,第一行没有MATCH语句。您正在两次匹配(a:person {name:"Moti Gol"})
并重新声明a
变量。
执行相同查询的更简单直观的方法:
// 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
答案 1 :(得分:1)
这是一个解决方案,我认为这是你从一开始就追求的,但并没有完全正确。
// 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
我认为这个解决方案会给你更多的成本确定性,因为它应该只遍历每个电影节点。如果朋友的朋友和朋友喜欢的电影中有很多重复(我认为这是一个相当可能的场景),那么首先将LIKED电影列表缩小到不同的列表然后根据之后观看的电影进行过滤可以节省数据库比较。