【问题标题】:having difficulties constructing an efficient query难以构建有效的查询
【发布时间】:2014-11-05 07:56:08
【问题描述】:

给定一个类似于包含 3000 名演员和 5000 部电影的电影数据库的模型,您将如何找到最常见的演员群体一起工作?

我已经尝试过类似的东西

match (a1:Actor)-[:ACTED_IN]-(m:Movie)-[:ACTED_IN]-(a2:Actor)
where a1<>a2
return distinct a1, count(m) as movieCount, a2  limit 999

但这会使服务器达到 99% 的 cpu 并且永远不会回来。此外,它只会给我配对,而不是组。

我尝试过 length(collect (m)) 或 collect a2,但似乎都没有返回与我的目标相关的内容。

如果您想尝试一下,并提供一两个指针,我们将不胜感激。

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    要使第一个查询起作用,请尝试

    MATCH (a1:Actor)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(a2:Actor)
    WITH a1, a2, COUNT(m) AS c
    WHERE c > 1
    RETURN DISTINCT a1, a2, c ORDER BY c DESC LIMIT 999
    

    您的 WHERE 子句不是必需的。

    我能想到的解决更大问题的最佳方法是创建组节点,然后研究结果。这是一个可以做到这一点的查询。可能需要一段时间。

    MATCH (m1:Movie)<-[:ACTED_IN]-(a:Actor)-[:ACTED_IN]->(m2:Movie)
    WITH m1, m2, COLLECT(a) AS actors, COLLECT(id(a)) as actorIDs
    WHERE LENGTH(actors) > 1
    MERGE (g:Group {actors : actorIDs})
        ON CREATE SET g.count = 1
        ON MATCH SET g.count = g.count + 1
    WITH g, actors
    UNWIND actors AS an
    MERGE (g)<-[:PART_OF]-(an)
    

    我在一张包含 300 名演员和 500 部电影的图表上对此进行了测试,每部电影中随机选择了 10 名演员。构建组花费了 48 秒。拥有组后,您可以对演员的数量、看到该组的次数等进行过滤和/或排序。

    我发现参与者节点 ID 的集合总是被排序的。如果不是这样,则查询可能无法正常工作,因为现有 :Group 节点上的合并可能不会成功。在这种情况下,您必须在收集它们之前对 :Actor 节点 ID 使用 ORDER BY。

    【讨论】:

    • 首先非常感谢您的响应和努力,我有点忘记了这个问题,因为我最终做了类似下面的事情(大约 2 秒后返回)。但是,在您的示例中了解 on create with merge 给了我一些想法,非常感谢
      match (a1:Actor)-[:ACTED_IN]-(c:Movie)-[r2:ACTED_IN]-(a2: Actor) 其中 a1a2 与 a1,count(r2) 作为 CC,a2 其中 CC > 2 与 collect(distinct(a2)) 作为收集,a1,a2,CC 返回不同的 a1.name,CC ,按 a1 收集的顺序.name desc 限制 900
    • 必须弄清楚如何更好地格式化评论:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 2020-06-24
    • 2012-08-03
    • 1970-01-01
    相关资源
    最近更新 更多