在 Neo4j/Cypher 中高效查找连接两组节点的唯一中间节点

问题描述

我有关于喜剧或戏剧电影的数据。我在那些电影中有演员,每部电影可以有多个角色。我想在以下位置找到所有不同的电影和演员集:

(drama1:Movie {Genre:'Drama'})-[role1]-(actor1:Actor)-[role2]-(comedy:Movie {Genre:'Comedy'})-[role3]-(actor2:演员)-[role4]-(drama2:Movie {Genre:'Drama'})

也就是说,我想找到两部(不同的)戏剧在喜剧中的联系,两部戏剧至少有一个演员。我正在努力有效地做到这一点,并让 Neo4j 为我提供不同的戏剧 1、戏剧 2、演员 1、演员 2、喜剧组。我的数据大约有几百万个节点和几千万个关系,因此效率很重要。一个可以插入到 neo4j 在线控制台的玩具设置是:

create (a:Movie {Genre:'Comedy'}),(b:Movie {Genre:'Comedy'}),(c:Movie {Genre:'Comedy'}),(d:Movie {Genre: '喜剧'}),(f:Movie {Genre:'Drama'}),(h:Movie {Genre:'Drama'}),(i:Actor {Name:'Sarah'}),(j:Actor { Name: 'Maria'}),(k:Actor {Name:'Mike'}),(l:Actor {Name:'Jane'}),(m:Actor {Name:'Sam'}),(q:演员 {Name:'Matt'}),(r:Actor {Name:'Tom'}),(i)-[:ActedIn]->(a),(i)-[:ActedIn]->(f),(j)-[:ActedIn ]->(b),(j)-[:ActedIn]->(h),(q)-[:ActedIn]->(c),( q)-[:ActedIn]->(b),(q)-[:ActedIn]->(a),(r)-[:ActedIn]->(f),(r)-[:ActedIn]- >(f),(r)-[:ActedIn]->(a),(j)-[:ActedIn]->(b),(j)-[:ActedIn]->(c),(k) -[:ActedIn]->(d),(l)-[:ActedIn]->(c),(i)-[:ActedIn]->( h),(m)-[:ActedIn]->(h)

我主要尝试过

的变体

匹配 (drama1:Movie {Genre:'Drama'})-[role1]-(actor1:Actor)-[role2]-(comedy:Movie {Genre:'Comedy'})-[role3]-(actor2 :Actor)-[role4]-(drama2:Movie {Genre:'Drama'})返回drama1,actor1,comedy,actor2,drama2

解决方法

您可以像这样使用多匹配查询:

MATCH p = (drama1:Movie {Genre:'Drama'})-[r1]-(a1)-[r2]-(comedy:Movie {Genre:'Comedy'})-[r3]-(a2)-[r4]-(drama2:Movie {Genre:'Drama'})
MATCH (drama1)-[]-(a:Actor)-[]-(drama2) 
WHERE drama1<>drama2 
RETURN nodes(p)

查询说明:

  • 第一场比赛找到两部由喜剧联系起来的戏剧
  • 第二个 MATCH 说明两部剧必须由同一个演员连接
  • WHERE 子句表示两部剧必须不同
  • RETURN 子句返回模式

优化查询没有什么可做的,因为您没有按任何属性进行过滤,因此您正在浏览整个图表。您可以尝试在“流派”属性上创建索引,但如果您只有两个不同的值,则不建议这样做。

另一种选择是使用 SKIP/LIMIT 以较小的批量检索模式:

MATCH p = (drama1:Movie {Genre:'Drama'})-[r1]-(a1)-[r2]-(comedy:Movie {Genre:'Comedy'})-[r3]-(a2)-[r4]-(drama2:Movie {Genre:'Drama'})
MATCH (drama1)-[]-(a:Actor)-[]-(drama2) 
WHERE drama1<>drama2 
RETURN nodes(p) SKIP 0 LIMIT 100000

此查询获取前 100k 个模式,然后您必须增加跳过以获取下一个 100k (SKIP 100000 LIMIT 100000)。通过这种方式,您必须运行 10 次查询才能获取所有模式。