找到与Kevin Bacon无关的演员,有效

时间:2017-04-27 21:20:05

标签: neo4j cypher bacon-number

使用neo4j cypher,哪些查询可以有效地找到与Kevin Bacon无关的演员?我们可以说'没有连接'意味着演员与凯文培根没有连接至少10跳,以简化。

以下是我的尝试:

MATCH (kb:Actor {name:'Kevin Bacon'})-[*1..10]-(h:Actor) with h 
MATCH (a)-[:ACTS_IN]->(m) 
WHERE a <> h 
RETURN DISTINCT h.name

但是,此查询运行3天。我怎样才能更有效地做到这一点?

1 个答案:

答案 0 :(得分:2)

(A)你的第一个MATCH发现每个与10个跃点连接的演员都要去Kevin Bacon。这个子句的结果是行数(M)(如果一个actor连接在一起,比如7个不同的方式连接到Kevin,那么这个actor用7行表示)。

(B)你的第二个MATCH找到在电影中扮演过角色的每个演员。如果这个MATCH子句是独立的,那么它将需要N行,其中N是ACTS_IN关系的数量(如果一个演员扮演了9个电影,那么该演员将被表示为9行)。但是,由于该子句紧跟在另一个MATCH子句之后,因此您获得了一个笛卡尔积,并且实际的结果行数是M * N.

因此,您的查询需要大量存储并执行(可能很大)冗余比较,并且您的结果可能包含重复的名称。要减少存储要求和参与者比较的数量(在WHERE子句中):您应该使A和B的结果具有不同的参与者,并消除笛卡尔积。

以下查询应该这样做。它首先收集每个不同演员的单个列表(在一行中),该演员在10个跃点内连接到Kevin Bacon(作为hs),然后找到所有(不同的)演员而不是在那个集合中:

MATCH (kb:Actor {name:'Kevin Bacon'})-[*..10]-(h:Actor)
WITH COLLECT(DISTINCT h) AS hs
MATCH (a:Actor) 
WHERE NOT a IN hs
RETURN a.name;

(此查询还节省了更多时间,因为没有费心去测试演员是否在电影中扮演过角色。)

然而,性能仍将取决于在第一个MATCH中执行可变长度路径搜索所需的时间。