多点两两之间的最短路径且经过某一个特定节点
发布于 6 年前 作者 crazyyanchao 5117 次浏览 来自 问答

原始查询(需要优化):

WITH [2842,18446,51149,63373,87863,101324,230869,25,69710] AS id_list
MATCH (v) WHERE id(v) IN id_list
  WITH collect(v) AS nodes
  UNWIND nodes AS source
  UNWIND nodes AS target
  WITH source,target WHERE id(source)<id(target)
MATCH paths = (source)-[*..3]-(n)-[*..3]-(target) WHERE id(n)=1053 WITH paths LIMIT 10
  RETURN paths

这种查询效率特别差:

MATCH p=allShortestPaths((source)-[*..6]-(target))
WHERE all(x in nodes(p) where id(x)=1231) return p LIMIT  10

论坛中有人说可以用下面(算法包)的方式优化,请教一下根据我的原始查询如何优化?返回需要是P路径

(1)可以使用neo4j图算法库的方法:
> 用The Dijkstra Shortest Path algorithm :  
MATCH (start:Loc{name:'A'}), (end:Loc{name:'F'})
CALL algo.shortestPath.stream(start, end, 'cost')
YIELD nodeId, cost
MATCH (other:Loc) WHERE id(other) = nodeId
RETURN other.name AS name, cost

(2)也可以把结果写回:
> MATCH (start:Loc{name:'A'}), (end:Loc{name:'F'})
CALL algo.shortestPath(start, end, 'cost',{write:true,writeProperty:'sssp'})
YIELD writeMillis,loadMillis,nodeCount, totalCost
RETURN writeMillis,loadMillis,nodeCount,totalCost
7 回复

MATCH p=allShortestPaths((source)-[*…6]-(target))–这句效果很差吗? 你这个数据有多少条? 我也用的这个效率还行 WHERE all(x in nodes§ where id(x)=1231) return p LIMIT 10

我执行下面的CYPHER根本跑不动啊,并且报:Neo.ClientError.Transaction.TransactionTimedOut

WITH [2842,18446,51149,63373,87863,101324,230869,25,69710] AS id_list
MATCH (v) WHERE id(v) IN id_list
  WITH collect(v) AS nodes
  UNWIND nodes AS source
  UNWIND nodes AS target
  WITH source,target WHERE id(source)<id(target)
MATCH paths = allShortestPaths((source)-[*..6]-(target))
WHERE all(x in nodes(paths) where id(x)=1053) WITH paths LIMIT 10
  RETURN paths

@daydayup 查询超时~ :) 执行的查询:

MATCH p=allShortestPaths((source)-[*..6]-(target))
WHERE id(source)=1059 AND id(target)=63373 AND any(x in nodes(p) where id(x)=1053) return p LIMIT  10

测试报错怕65030.png

我最后的查询方法是这样,因为固定距离上的节点已经查询出来了,只需要保证路径可达即可(最长查询6层关系) 至于上面那个问题还没解决,如果有测试过的朋友请留下个脚印(测试好几遍上面的all/any函数查询没法用太慢),下面的查询看起来简陋但是目前暂时满足了需求 另外[…3]-()-[…3],[…3]-()-[…2],[…5],路径的不同设置效率是不一样的([…3]-()-[*…3]满足需求且效率还可以接受百万级节点),具体测试用PROFILE查看一下

MATCH p = (n:Label1)-[*..3]-()-[*..3]-(f:Label2)-[*..3]-()-[*..3]-(m:Label3) WHERE id(n)=2842 AND id(f)=51172 AND id(m)=51149  RETURN p LIMIT 10

@daydayup 我是已经用allShortestPaths找到了最短路径,然后这些点放在一个地方,已知开始结束点,然后用中间那些点再查一次,相当于再把最短路径过滤一遍。 试过了去掉WHERE挺快的。

这种查询查不出东西我也是很奇怪(巨慢无比)~:)

MATCH p=allShortestPaths((source)-[*..6]-(target))
WHERE all(x in nodes(p) where id(x)=1231) return p LIMIT  10

@daydayup 问题就在这里,为啥用WHERE之后巨慢无比,不用WHERE速度还可以接受

dbms.transaction.timeout=180s
回到顶部