neo4j 匹配两个不同的关系并检索计数同时避免笛卡尔积
neo4j matching two different relationships and retrieving count while avoiding cartesian product
所以我有一个数据库,我想在其中检索具有“已评论”关系的结果,在这个结果中我想检索具有关系“acted_in”和 return 电影的实体演员人数最多。
这是我写的代码:
MATCH (a:Person)-[r2:REVIEWED]->(movie:Movie)<-[r:ACTED_IN]-(actors:Person)
RETURN movie.title as Movie_name, count(actors) as no_of_cast
ORDER BY no_of_cast DESC
Limit 1
它 return 是正确的电影名称,但演员人数是评论者和参演者的笛卡尔积。
我在 actors 上收集函数后得到的结果是
"The Replacements" ["Brooke Langton", "Keanu Reeves", "Orlando Jones", "Gene Hackman", "Brooke Langton", "Keanu Reeves", "Orlando Jones", "Gene Hackman", "Brooke Langton", "Keanu Reeves", "Orlando Jones", "Gene Hackman"]
它会根据该电影节点中出现关系“已审核”的次数重复演员。
我怎样才能避免这种情况并获得正确的演员人数,即 4。谢谢。
之所以得到multiple/duplicate个演员是因为同一部电影正在被不止一个人(评论者)评论。要删除重复项,您可以使用关键字“DISTINCT”。
MATCH (a:Person)-[r2:REVIEWED]->(movie:Movie)<-[r:ACTED_IN]-(actors:Person)
RETURN movie.title as Movie_name, count(distinct actors) as no_of_cast
ORDER BY no_of_cast DESC
结果:
╒═══════════════════╤════════════╕
│"Movie_name" │"no_of_cast"│
╞═══════════════════╪════════════╡
│"The Replacements" │4 │
├───────────────────┼────────────┤
│"Cloud Atlas" │4 │
├───────────────────┼────────────┤
│"The Da Vinci Code"│4 │
├───────────────────┼────────────┤
│"The Birdcage" │3 │
├───────────────────┼────────────┤
│"Unforgiven" │3 │
└───────────────────┴────────────┘
您还有一些其他的改进选项。
您真的不想要包含审阅者的路径,这就是导致交叉产品(审阅者行 x 演员行)的原因。相反,这是一个条件,您唯一感兴趣的电影是那些有人评论过的电影。您可以将模式的那部分移至 WHERE 子句:
MATCH (movie:Movie)
WHERE ()-[:REVIEWED]->(movie)
WITH movie, size((movie)<-[:ACTED_IN]-()) as no_of_cast
ORDER BY no_of_cast DESC
LIMIT 1
RETURN movie.title as Movie_name, no_of_cast
另请注意,我们不是进行聚合,而是使用 size() 获取节点上 :ACTED_IN 关系的度数以获取转换次数。这样效率更高,因为我们不需要执行任何扩展或聚合来获取此值。
此外,我们还在等到我们获得单项最高结果后才能投射该标题 属性。 属性 访问费用可能很高,因此最好推迟访问,直到获得最小结果集。
所以我有一个数据库,我想在其中检索具有“已评论”关系的结果,在这个结果中我想检索具有关系“acted_in”和 return 电影的实体演员人数最多。
这是我写的代码:
MATCH (a:Person)-[r2:REVIEWED]->(movie:Movie)<-[r:ACTED_IN]-(actors:Person)
RETURN movie.title as Movie_name, count(actors) as no_of_cast
ORDER BY no_of_cast DESC
Limit 1
它 return 是正确的电影名称,但演员人数是评论者和参演者的笛卡尔积。
我在 actors 上收集函数后得到的结果是
"The Replacements" ["Brooke Langton", "Keanu Reeves", "Orlando Jones", "Gene Hackman", "Brooke Langton", "Keanu Reeves", "Orlando Jones", "Gene Hackman", "Brooke Langton", "Keanu Reeves", "Orlando Jones", "Gene Hackman"]
它会根据该电影节点中出现关系“已审核”的次数重复演员。
我怎样才能避免这种情况并获得正确的演员人数,即 4。谢谢。
之所以得到multiple/duplicate个演员是因为同一部电影正在被不止一个人(评论者)评论。要删除重复项,您可以使用关键字“DISTINCT”。
MATCH (a:Person)-[r2:REVIEWED]->(movie:Movie)<-[r:ACTED_IN]-(actors:Person)
RETURN movie.title as Movie_name, count(distinct actors) as no_of_cast
ORDER BY no_of_cast DESC
结果:
╒═══════════════════╤════════════╕
│"Movie_name" │"no_of_cast"│
╞═══════════════════╪════════════╡
│"The Replacements" │4 │
├───────────────────┼────────────┤
│"Cloud Atlas" │4 │
├───────────────────┼────────────┤
│"The Da Vinci Code"│4 │
├───────────────────┼────────────┤
│"The Birdcage" │3 │
├───────────────────┼────────────┤
│"Unforgiven" │3 │
└───────────────────┴────────────┘
您还有一些其他的改进选项。
您真的不想要包含审阅者的路径,这就是导致交叉产品(审阅者行 x 演员行)的原因。相反,这是一个条件,您唯一感兴趣的电影是那些有人评论过的电影。您可以将模式的那部分移至 WHERE 子句:
MATCH (movie:Movie)
WHERE ()-[:REVIEWED]->(movie)
WITH movie, size((movie)<-[:ACTED_IN]-()) as no_of_cast
ORDER BY no_of_cast DESC
LIMIT 1
RETURN movie.title as Movie_name, no_of_cast
另请注意,我们不是进行聚合,而是使用 size() 获取节点上 :ACTED_IN 关系的度数以获取转换次数。这样效率更高,因为我们不需要执行任何扩展或聚合来获取此值。
此外,我们还在等到我们获得单项最高结果后才能投射该标题 属性。 属性 访问费用可能很高,因此最好推迟访问,直到获得最小结果集。