neo4j 匹配两种不同的关系并检索计数,同时避免笛卡尔积

问题描述

所以我有一个数据库,我想在其中检索具有“Reviewed”关系的结果,在这个结果中,我想检索具有“acted_in”关系的实体并返回演员人数最多的电影。

这是我写的代码

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

它返回正确的电影名称,但演员人数是评论人和演员的笛卡尔积。

在actor上执行collect函数后得到的结果是

"The Replacements"  ["brooke Langton","Keanu Reeves","Orlando Jones","Gene Hackman","brooke Langton","Gene Hackman"]

它向演员重复该电影节点中存在“评论”关系的次数

我怎样才能避免这种情况并获得正确的演员人数,即 4。谢谢。

解决方法

你得到多个/重复演员的原因是因为同一部电影被不止一个人(评论者)审阅。要删除重复项,您可以使用关键字“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 关系的度数以获取转换次数。这更有效,因为我们不需要执行任何扩展或聚合来获得此值。

此外,我们还要等到获得单一最高结果后才能投影该标题属性。属性访问可能很昂贵,因此最好推迟它,直到您获得最小的结果集。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...