问题描述
我对 Gremlin 很陌生,我试图在我的图中找到从 source_id 顶点到 target_id 顶点的最轻路径。 (在某些边缘我有权重,而在其他边缘我没有)
获得最短路径:
g.V()
.has("id",source_id)
.repeat(outV().simplePath())
.until(has("id",target_id))
.path()
.limit(3)
.toList()
)
它建议使用类似的东西:
g.V()
.has("id",source_id)
.repeat(out()).simplePath())
.until(has("id",target_id))
.path()
.by(coalesce(values("weight"),constant(0.0)))
.limit(limit)
.toList()
)
这不起作用并返回路径的权重, 我怎样才能用 Gremlin 做到这一点?应该首先获取路径,计算它们的权重,然后按权重对它们进行排序?必须有一种更简单直观的方式来满足这一基本需求。 (如果是 neo4j,我可以运行 Dijkstra 的算法)
希望得到一些帮助, 谢谢
解决方法
我创建了以下示例图来帮助说明这个答案。
gremlin> g.addV('A').as('a').
......1> addV('B').as('b').
......2> addV('C').as('c').
......3> addV('D').as('d').
......4> addV('E').as('e').
......5> addV('F').as('f').
......6> addV('G').as('g').
......7> addV('H').as('h').
......8> addV('Z').as('z').
......9> addE('knows').from('a').to('b').property('weight',0.2).
.....10> addE('knows').from('a').to('c').property('weight',0.5).
.....11> addE('knows').from('a').to('f').property('weight',3.5).
.....12> addE('knows').from('b').to('c').property('weight',0.1).
.....13> addE('knows').from('c').to('d').property('weight',0.3).
.....14> addE('knows').from('c').to('e').property('weight',0.2).
.....15> addE('knows').from('c').to('f').
.....16> addE('knows').from('d').to('f').property('weight',0.1).
.....17> addE('knows').from('d').to('g').property('weight',2.0).
.....18> addE('knows').from('f').to('g').property('weight',0.9).
.....19> addE('knows').from('f').to('h').property('weight',0.3).
.....20> addE('knows').from('f').to('z').property('weight',0.1).
.....21> addE('knows').from('h').to('z').property('weight',0.2).iterate()
从 A 到 Z 存在以下路径(不考虑边权重)。
gremlin> g.V().hasLabel('A').
......1> repeat(outE().inV().simplePath()).until(hasLabel('Z')).path().by(label)
==>[A,knows,F,Z]
==>[A,H,C,B,D,Z]
请注意,其中一条边没有权重。我们可以找到权重最轻的路径(其中没有权重被视为零值)如下:
gremlin> g.withSack(0).V().
......1> hasLabel('A').
......2> repeat(outE().sack(sum).by(coalesce(values('weight'),constant(0))).inV()).
......3> until(hasLabel('Z')).
......4> order().by(sack(),asc).
......5> path().
......6> by(label)
==>[A,Z]
为了证明事情按预期进行,我们可以将总权重值添加到每个结果中。
gremlin> g.withSack(0).V().
......1> hasLabel('A').
......2> repeat(outE().sack(sum).by(coalesce(values('weight'),asc).
......5> local(
......6> union(
......7> path().
......8> by(label),......9> sack()).
.....10> fold())
==>[[A,Z],0.4]
==>[[A,0.6]
==>[[A,0.8]
==>[[A,1.0]
==>[[A,1.2]
==>[[A,1.4]
==>[[A,3.6]
==>[[A,4.0]