在Neo4j/Cypher中有效地找到连接两组节点的唯一中间节点

在Neo4j/Cypher中有效地找到连接两组节点的唯一中间节点,neo4j,cypher,Neo4j,Cypher,我有关于喜剧或戏剧电影的资料。我在这些电影中有演员,他们可以在每部电影中扮演多个角色。我想找到所有不同类型的电影和演员,其中: (戏剧一:电影{类型:'戏剧'})-(角色一)-(演员一:演员)-(角色二)-(喜剧:电影{类型:'喜剧'})-(角色三)-(演员二:演员)-(角色四)-(戏剧二:电影{类型:'戏剧') 也就是说,我想找出两部(不同的)戏剧通过一部喜剧连接在一起,两部戏剧至少有一个演员。我正在努力有效地做到这一点,并让neo4j为我提供不同的戏剧1、戏剧2、演员1、演员2、喜剧组。我的

我有关于喜剧或戏剧电影的资料。我在这些电影中有演员,他们可以在每部电影中扮演多个角色。我想找到所有不同类型的电影和演员,其中:

(戏剧一:电影{类型:'戏剧'})-(角色一)-(演员一:演员)-(角色二)-(喜剧:电影{类型:'喜剧'})-(角色三)-(演员二:演员)-(角色四)-(戏剧二:电影{类型:'戏剧')

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

创作(a:电影{流派:'喜剧'}),(b:电影{流派:'喜剧'}),(c:电影{流派:'喜剧'}),(d:电影{流派:'喜剧'},(f:电影{流派:'戏剧'}),(h:电影{流派:'戏剧'},(i:演员{姓名:'Sarah'}),(j:演员{姓名:'Maria'},(k:演员{姓名:'Mike'}),(l:演员{姓名:'Jane'}),(m:演员{姓名:'Sam Sam q:演员,{姓名:'Matt',i:{姓名:{-(a)的,(i)的,(i)的,(i)的,(i)的,(i)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的,(c)的)的,(q)的)的,(c)的)的,(c)的)的,(,(q)的)的)的)是,(b)的,(b)的)的,(q)的)的)的,(q)的)的)的)的)的)的,(,(,(q)的)的)的)的)的)的)的,(,(,(,(,(,(,(q)的)的)的)的)的)的)的)的)的)的)的)的)的)的)的)的,(,(,(,(,(,(b)的)的)的)的)的)的)的)的)的)的)(k)-(d),(l)-(c),(i)-(a),(i)-(h),(m)-(h)

我大部分时间都在尝试不同的


匹配(戏剧1:电影{流派:'戏剧'})-[role1]-(actor1:演员)-[role2]-(喜剧:电影{流派:'喜剧'})-[role3]-(actor2:演员)-[role4]-(戏剧2:电影{流派:'戏剧'})返回戏剧1,actor1,喜剧,actor2,戏剧2

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

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 p=(戏剧1:电影{流派:'戏剧'})-[r1]-(a1)-[r2]-(喜剧:电影{流派:'喜剧'})-[r3]-(a2)-[r4]-(戏剧2:电影{流派:'戏剧'})
比赛(戏剧一)演员(戏剧二)
戏剧在哪里
返回节点(p)
查询说明:

  • 第一场比赛发现两部戏剧由喜剧连接
  • 第二个匹配告诉我们这两部剧必须由同一个演员连接
  • 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
MATCH p=(戏剧1:电影{流派:'戏剧'})-[r1]-(a1)-[r2]-(喜剧:电影{流派:'喜剧'})-[r3]-(a2)-[r4]-(戏剧2:电影{流派:'戏剧'})
比赛(戏剧一)演员(戏剧二)
戏剧在哪里
返回节点(p)跳过0限制100000

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

在我的玩具数据集上看起来不错,但在我真正的百万节点数据集上却不运行。有没有关于如何进一步优化查询的想法?@Robmattles很难优化,因为您没有按任何属性进行筛选,但可以一点一点地获得模式。我编辑答案以解释不是这样。