只需要跨多个路径的公共节点 - Neo4j Cypher

时间:2016-02-05 17:23:00

标签: path neo4j cypher intersect

我的Cypher查询找到几个起始节点的公共子节点。每条路径只有它的节点id被提取并返回,导致每条路径中有数百行。参见p1和p2示例(仅显示3行和2个起点)。

Match p1=(n1:node{name:"x" })-[r:sub*]->(i)), p2=(n2:node{name:"y" })-[r:sub*]->(i))
RETURN DISTINCT i, extract(a IN nodes(p1)| a.id) as p1, extract(b IN nodes(p2)| b.id) as p2

----RESULTS----

p1=1,4,3
p1=1,8,3
p1=1,8,9,3 

p2=6,7,3
p2=6,5,9,3
p2=6,7,10,3

我想要的是在查询期间将cypher中的路径相交,以便我不必在之后执行此操作。在php中我会迭代使用:

$result = array_intersect($p1,$p2);

这将从上面的示例中返回9,3,因为它们是所有路径共享的唯一公共节点。有没有办法在Cypher中执行此操作,以便我不会返回数百行?

谢谢!

1 个答案:

答案 0 :(得分:0)

我相信这会满足您的需求。

以下是正在考虑的数据的图片。 enter image description here

// match the two different paths with the common ending i
match p1=(n1:Node {name: 1 })-[:SUB*]->(i)
, p2=(n2:Node {name: 6 })-[:SUB*]->(i)

// collect both sets of paths for every 
with i, collect(p1) as p1, collect(p2) as p2

// recombine the nodes of the first path(s) as distinct collections of nodes
unwind p1 as p
unwind nodes(p) as n
with i, p2, collect( distinct n ) as p1

// recombine the nodes of the second path(s) as distinct collections of     
unwind p2 as p
unwind nodes(p) as n
with i, p1, collect( distinct n ) as p2

// return the common ending node with the nodes common to each path
return i, [n in p1 where n in p2 | n.name] as n

编辑更新解决方案以包含第三条路径

// match the two different paths with the common ending i
match p1=(n1:Node {name: 1 })-[:SUB*]->(i)
, p2=(n2:Node {name: 6 })-[:SUB*]->(i)
, p3=(n3:Node {name: 4 })-[:SUB*]->(i)

// collect both sets of paths for every 
with i, collect(p1) as p1, collect(p2) as p2, collect(p3) as p3

// recombine the nodes of the first path(s) as distinct collections of nodes
unwind p1 as p
unwind nodes(p) as n
with i, p2, p3, collect( distinct n ) as p1

// recombine the nodes of the second path(s) as distinct collections of     
unwind p2 as p
unwind nodes(p) as n
with i, p1, p3, collect( distinct n ) as p2

// recombine the nodes of the third path(s) as distinct collections of     
unwind p3 as p
unwind nodes(p) as n
with i, p1, p2, collect( distinct n ) as p3

// return the common ending node with the nodes common to each path
return i, [n in p1 where n in p2 and n in p3 | n.name] as n