【问题标题】:neo4j matching two different relationships and retrieving count while avoiding cartesian productneo4j 匹配两个不同的关系并检索计数,同时避免笛卡尔积
【发布时间】:2021-08-14 09:48:35
【问题描述】:

所以我有一个数据库,我想在其中检索具有“已审核”关系的结果,并在此结果中检索具有“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

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

对actors进行collect函数后得到的结果是

"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。谢谢。

【问题讨论】:

  • 也许您的数据库实体和关系的小架构会有所帮助?
  • @Antonin;它是电影数据库,所以它是安装 neo4j 桌面时的示例数据库。

标签: neo4j cartesian-product


【解决方案1】:

您获得多个/重复演员的原因是因为同一部电影正在由多个人(评论者)进行评论。要删除重复项,您可以使用关键字“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           │
└───────────────────┴────────────┘

【讨论】:

    【解决方案2】:

    您还有其他一些改进选择。

    您并不真正想要包含审阅者的路径,这就是导致交叉产品(审阅者行 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 关系的度数,以获得演员的数量。这更有效,因为我们不需要执行任何扩展或聚合来获取此值。

    此外,我们还在等到获得单项最高结果后才能投影该 title 属性。属性访问可能很昂贵,因此最好将其推迟到您获得最小结果集。

    【讨论】:

    • 它没有给出正确的输出。它再次返回一个产品,其中 no_of_cast 为 172。
    • 你是对的,它没有给出正确的输出,但这不是因为任何交叉产品。我忘记在尺寸模式中添加 movie 引用,因此它返回的是整个图中的 :ACTED_IN 关系的总数,而不是该行上的特定节点。这是解决方法:size((movie)&lt;-[:ACTED_IN]-()),请注意 (movie) 在这里如何限制模式,因此我们只寻找特定节点的传入 :ACTED_IN 关系的程度。
    猜你喜欢
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2014-08-15
    • 2023-03-06
    • 2019-10-20
    • 1970-01-01
    • 2019-08-26
    相关资源
    最近更新 更多