2014-11-05 50 views
2

给出一个模型类似于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,永不回来。而且,它只会给我配对,而不是群体。

我试过了(收集(m))或收集a2,但都没有返回与我的目标相关的东西。

anywho如果你想刺探它,并提供一个或两个指针,将不胜感激。

回答

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 

您的条款。

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

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。

+0

首先非常感谢你的回应和努力,我有点忘了这个问题,因为我最终做了类似于下面的事情(大概在2秒内回来)。 但是在你的例子中学习关于合并创建给了我一些想法,所以非常感谢那

match (a1:Actor)-[:ACTED_IN]-(c:Movie)-[r2:ACTED_IN]-(a2:Actor) where a1<>a2 with a1, count(r2) as CC, a2 where CC > 2 with collect(distinct(a2)) as collected, a1,a2,CC return distinct a1.name,CC ,collected order by a1.name desc limit 900
cechode 2014-11-10 20:39:34

+0

必须弄清楚如何格式化评论更好:) – cechode 2014-11-10 20:40:47