高效地寻找与凯文培根无关的演员
Finding actors not connected to Kevin Bacon, efficiently
使用 neo4j cypher,什么查询可以有效地找到与 Kevin Bacon 没有联系的演员?为简单起见,我们可以说 'not connected' 意味着演员与 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 天。我怎样才能更有效地做到这一点?
(A) 您的第一个 MATCH
找到在 10 跳内连接到 Kevin Bacon 的每个演员。该子句的结果是行数 (M)(如果一个演员以 7 种不同的方式连接到 Kevin,则该演员以 7 行表示)。
(B) 您的第二个 MATCH
查找所有出演过电影的演员。如果这个 MATCH
子句是独立的,那么它将需要 N 行,其中 N 是 ACTS_IN
关系的数量(如果一个演员出演了 9 部电影,那么该演员将被表示为9 行)。但是,由于该子句紧跟在另一个 MATCH
子句之后,您将得到一个笛卡尔积,结果行的实际数量为 M*N。
因此,您的查询需要大量存储并执行(可能很大)数量的冗余比较,并且您的结果可能包含重复名称。为了减少存储要求和参与者比较的次数(在您的 WHERE
子句中):您应该使 A 和 B 的结果具有不同的参与者,并消除笛卡尔积。
下面的查询应该可以做到这一点。它首先收集每个 distinct actor 的单个列表(在一行中),该 actor 在 10 跳内连接到 Kevin Bacon(如 hs
),然后找到所有(distinct ) 不在该集合中的演员:
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
中执行可变长度路径搜索需要多长时间。
使用 neo4j cypher,什么查询可以有效地找到与 Kevin Bacon 没有联系的演员?为简单起见,我们可以说 'not connected' 意味着演员与 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 天。我怎样才能更有效地做到这一点?
(A) 您的第一个 MATCH
找到在 10 跳内连接到 Kevin Bacon 的每个演员。该子句的结果是行数 (M)(如果一个演员以 7 种不同的方式连接到 Kevin,则该演员以 7 行表示)。
(B) 您的第二个 MATCH
查找所有出演过电影的演员。如果这个 MATCH
子句是独立的,那么它将需要 N 行,其中 N 是 ACTS_IN
关系的数量(如果一个演员出演了 9 部电影,那么该演员将被表示为9 行)。但是,由于该子句紧跟在另一个 MATCH
子句之后,您将得到一个笛卡尔积,结果行的实际数量为 M*N。
因此,您的查询需要大量存储并执行(可能很大)数量的冗余比较,并且您的结果可能包含重复名称。为了减少存储要求和参与者比较的次数(在您的 WHERE
子句中):您应该使 A 和 B 的结果具有不同的参与者,并消除笛卡尔积。
下面的查询应该可以做到这一点。它首先收集每个 distinct actor 的单个列表(在一行中),该 actor 在 10 跳内连接到 Kevin Bacon(如 hs
),然后找到所有(distinct ) 不在该集合中的演员:
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
中执行可变长度路径搜索需要多长时间。