Neo4j - Cypher:与遍历关系的共同对象

时间:2014-09-29 09:14:34

标签: graph neo4j cypher

我有一个小图表:

CREATE 
(Dic1:Dictioniary { name:'Dic1' }),
(Dic2:Dictioniary { name: 'Dic2' }),
(Dic3:Dictioniary { name: 'Dic3' }),
(File1:File { name: 'File1' }),
(File2:File { name: 'File2' }),
(File3:File { name: 'File3' }),
(Dic2)-[:contains]->(Dic1),
(Dic1)-[:contains]->(File1),
(Dic3)-[:contains]->(File2),
(File1)-[:references]->(File3),
(File2)-[:references]->(File3)

我需要一个密码查询来查找,例如Dic2和Dic3是否有路径/关系,它们引用相同的文件。 在这种情况下,这是真的;相互文件是File3。

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

当您只查找两个词典时,您可以在一个语句中实现此目的:

MATCH (d2:Dictioniary { name:'Dic2' }),(d3:Dictioniary { name:'Dic3' })
MATCH (d2)-[:contains|references*]->(f:File)<-[:contains|references*]-(d3)
RETURN f

由于两个无限制的路径匹配,它非常昂贵,但它非常便宜,因为它从一开始就受到两个字典匹配的约束。

如果您要测试任意数量的词典,可以执行以下操作:

MATCH (d1:Dictioniary { name:'Dic1' }),(d2:Dictioniary { name:'Dic2' }),(d3:Dictioniary { name:'Dic3' })
WITH [d1,d2,d3] AS ds
MATCH (d)-[:contains|references*]->(f:File)
WHERE d IN ds
WITH f, ds, COLLECT(d) AS fds
WHERE length(ds)= length(fds)
RETURN f

这首先匹配您感兴趣的词典,并且每个词典依次找到它们引用的文件。重要的是保留File对象,并将引用它的Dictionary收集到一个数组(fds)中。如果我们知道我们有3个字典(length(ds))并且给定文件具有相同数量的相关字典(length(fds)),那么所有字典都必须引用它。

假设给定字典中的给定文件可能有多条路径,那么您可以将DISTINCT修饰符插入第二个WITH语句中:

WITH f, ds, COLLECT(DISTINCT(d)) AS fds