Gremlin 小精灵在顶点之间找到最轻的路径

Gremlin 小精灵在顶点之间找到最轻的路径,gremlin,graph-databases,gremlinpython,Gremlin,Graph Databases,Gremlinpython,我对Gremlin很陌生,我正试图在我的图中找到从源id顶点到目标id顶点的最轻路径。(在某些边上我有重量,而在其他边上我没有重量) 要获得我可以使用的最短路径,请执行以下操作: g.V() .has("id", source_id) .repeat(outV().simplePath()) .until(has("id", target_id))

我对Gremlin很陌生,我正试图在我的图中找到从源id顶点到目标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()
        )
这不起作用并返回路径的权重, 我怎样才能用小精灵做到这一点?应该首先获取路径,计算它们的权重,然后根据权重对它们进行排序吗?必须有一种更简单直观的方法来满足这一基本需求。(如果是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.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,knows,B,knows,C,knows,F,knows,Z]
==>[A,knows,C,knows,F,knows,Z]
==>[A,knows,B,knows,C,knows,D,knows,F,knows,Z]
==>[A,knows,B,knows,C,knows,F,knows,H,knows,Z]
==>[A,knows,C,knows,D,knows,F,knows,Z]
==>[A,knows,C,knows,F,knows,H,knows,Z]
==>[A,knows,B,knows,C,knows,D,knows,F,knows,H,knows,Z]
==>[A,knows,C,knows,D,knows,F,knows,H,knows,Z]
==>[A,knows,F,knows,Z]
==>[A,knows,F,knows,H,knows,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>       local(
......6>         union(
......7>           path().
......8>             by(label),
......9>           sack()).
.....10>         fold())
==>[[A,knows,B,knows,C,knows,F,knows,Z],0.4]
==>[[A,knows,C,knows,F,knows,Z],0.6]
==>[[A,knows,B,knows,C,knows,D,knows,F,knows,Z],0.8]
==>[[A,knows,B,knows,C,knows,F,knows,H,knows,Z],0.8]
==>[[A,knows,C,knows,D,knows,F,knows,Z],1.0]
==>[[A,knows,C,knows,F,knows,H,knows,Z],1.0]
==>[[A,knows,B,knows,C,knows,D,knows,F,knows,H,knows,Z],1.2]
==>[[A,knows,C,knows,D,knows,F,knows,H,knows,Z],1.4]
==>[[A,knows,F,knows,Z],3.6]
==>[[A,knows,F,knows,H,knows,Z],4.0]   

只是想澄清一下,你想要的是总分最低的路径?如果是这样,将这些权重存储在
sack
中,然后按
sack
值排序是一种方法。如果你能确认这是你需要的,我可以提供一个例子。您找到的代码片段处理了边可能没有权重但不尝试排序的情况。
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>       local(
......6>         union(
......7>           path().
......8>             by(label),
......9>           sack()).
.....10>         fold())
==>[[A,knows,B,knows,C,knows,F,knows,Z],0.4]
==>[[A,knows,C,knows,F,knows,Z],0.6]
==>[[A,knows,B,knows,C,knows,D,knows,F,knows,Z],0.8]
==>[[A,knows,B,knows,C,knows,F,knows,H,knows,Z],0.8]
==>[[A,knows,C,knows,D,knows,F,knows,Z],1.0]
==>[[A,knows,C,knows,F,knows,H,knows,Z],1.0]
==>[[A,knows,B,knows,C,knows,D,knows,F,knows,H,knows,Z],1.2]
==>[[A,knows,C,knows,D,knows,F,knows,H,knows,Z],1.4]
==>[[A,knows,F,knows,Z],3.6]
==>[[A,knows,F,knows,H,knows,Z],4.0]