Cypher查询:查找大图上的最小和最大关系长度

时间:2018-03-08 11:25:38

标签: neo4j cypher

目标:查找两种节点类型之间的最小和最大关系长度。

示例: 以下是节点类型的虚拟连接' T'

  • (Aplha)-->(Bravo)
  • (Bravo)-->(Charlie)

所以到达两个节点​​的最小跳数是1(即Aplha直接链接到Charlie),到达两个节点​​的最大跳数是2(即(Aplha)--(Beta)--(Charlie))。

Cypher查询我就像:

MATCH (from:T), (to:T), p=shortestPath((from)-[*]-(to))
RETURN min(length(p)) as min, max(length(p)) as max

哪种方法适用于较小的数据集,但对于2000个节点则适用于'和2000个节点是'到'与min:5和max:10 hops等级相关联,此查询需要 30分钟才能运行

有没有办法实现这种操作是一种更快的方式?

我不能使用的解决方案:

  • 限制关系长度:我必须使用(from)-[*]-(to),不能将其限制为3或4级。

1 个答案:

答案 0 :(得分:4)

使用APOC's path expander procedures(仅适用于3.2.x或3.3.x的2018年冬季最新版本),最低限度非常简单。

您可以使用一个组作为起始节点,并使用标签过滤器中的:T标签作为终止标签(扩展路径的末尾)并添加限制:

MATCH (start:T)
WITH collect(start) as startNodes
CALL apoc.path.expandConfig(startNodes, {labelFilter:'/T', limit:1, minLevel:1, uniqueness:'NODE_GLOBAL'}) YIELD path
RETURN length(path) as min

我们正在使用expandConfig()和NODE_GLOBAL唯一性,这在扩展过程中会有很大的帮助,因为我们可以修剪(不需要考虑)任何已经访问过的节点的路径。

当您查找具有特定标签的节点的路径时,路径扩展器程序非常好,请注意,我们不需要匹配端节点并创建交叉产品,我们将在扩展期间评估节点标签,并停止当到达具有:T标签的节点时。

limit:1将在找到第一个结果时自动停止,并且扩展使用广度优先搜索,因此第一个匹配将是可能的最短路径。

为了找到所有最短路径中最长的路径(从每个路径:T节点到最近的路径:T节点),方法类似,但我们不会收集结果,因此程序将针对每个路径执行: T节点。

MATCH (start:T)
CALL apoc.path.expandConfig(start, {labelFilter:'/T', limit:1, minLevel:1, uniqueness:'NODE_GLOBAL'}) YIELD path
RETURN max(length(path)) as maxShortest

为了找到每两个之间最长的最短路径:但是,T节点的性能可能会更差。

我们可以使用类似的方法,但我们将删除LIMIT,并更改标签过滤器以使用:T作为终端节点(路径必须以:T节点结束,但可以扩展到它们以找到其他路径:T节点)

MATCH (start:T)
CALL apoc.path.expandConfig(start, {labelFilter:'>T', minLevel:1, uniqueness:'NODE_GLOBAL'}) YIELD path
RETURN max(length(path)) as maxShortestOfAllPairs