Neo4j:仅返回图中丢弃普通子节点的第一个公共节点

时间:2018-05-28 20:54:55

标签: neo4j cypher

从蓝色节点开始我想以蓝色比较每个节点以寻找它们的第一个公共子节点。(绿色)我下面的当前查询是将第一个公共节点返回到所有起始值以及所有普通子节点节点。 (红色:左图)

如何过滤结果,只返回第一个公共节点(绿色),丢弃白色和红色节点。

我从2到10个值开始,当只需要几个根节点时,当前可以有超过100个结果行。我想我需要收集结果,然后在集合上进行另一种模式匹配 - 也许比较寻找第一个公共节点的路径。每个起始集可能有几个根(绿色)节点。

感谢您的帮助!

MATCH (val0:v {value:”532”} )-[r*0..50]->(x:n)  WITH x
MATCH (val1:v {value:”234”} )-[r*0..50]->(x:n)  WITH x
MATCH (val2:v {value:”678”} )-[r*0..50]->(x:n) 

RETURN DISTINCT con

enter image description here

1 个答案:

答案 0 :(得分:1)

我认为你有正确的想法,收集结果,然后做一些其他匹配,以找出要保留的结果。我认为APOC Procedures可以在这里提供帮助,因为path finding procs在到达某些节点时可以停止(terminatorNodes配置参数)。

您还希望在整个过程中收集结果,这样您就不会增加需要完成的工作量。例如,第一次匹配的x行数将乘以执行第二次匹配的次数。如果我们在整个过程中将结果收集到列表中,那么我们只执行一次每次扩展而不是每行乘法(Cypher操作每行执行一次)。我们可以使用列表交集(来自APOC)来获取沿途的共同节点。

然后我们可以使用路径查找程序来从任何起始节点中找到路径,并使用终止节点过滤器,这样当我们到达其中一个公共节点结果(这将是绿色节点)时,探索的每个路径都将停止要)。

这是一个可能适合您的示例:

MATCH (val0:v {value:"532"} )-[*0..50]->(x:n)
WITH collect(distinct x) as results
MATCH (val1:v {value:"234"} )-[*0..50]->(x:n)  
WITH apoc.coll.intersection(results, collect(distinct x)) as results
MATCH (val2:v {value:"678"} )-[*0..50]->(x:n) 
WITH apoc.coll.intersection(results, collect(distinct x)) as results
MATCH (start:v {value:"532"} )
CALL apoc.path.subgraphNodes(start, {terminatorNodes:results}) YIELD node as firstCommon
RETURN firstCommon

修改

就非APOC方法而言,这样的事情可能有效,取代apoc.path.subgraphNodes()电话:

...
MATCH p=(start:Root {id:532} )-[*0..50]->(x)
WHERE x in results and single(node in nodes(p) where node in results)
RETURN distinct x