使用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天。我怎样才能更有效地做到这一点?
答案 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
中执行可变长度路径搜索所需的时间。