在树查询中重复遍历有序边的问题

Repeat issue traversing ordered edges in tree query

我有一个图,其中一个顶点有来自同一父项的多条边。我只需要根据最高 属性 值遍历一条边来创建一棵树。

我使用“order().by”来选择边缘。适用于一级查询。一旦我尝试为一棵树重复,就会出现一个我不明白的错误: "reducing barrier 的父级不能重复()-step: GroupStep([EdgeVertexStep(IN)],[FoldStep])"

图表:

g.addV("O").property("name",'A').as('A').
  addV("O").property("name",'B').as('B').
  addV("O").property("name",'C').as('C').
  addV("O").property("name",'D').as('D').
  addV("O").property("name",'E').as('E').
  addV("O").property("name",'F').as('F').
  addE("R").property("ver","1").from('A').to('B').
  addE("R").property("ver","2").from('A').to('B').
  addE("R").property("ver","1").from('A').to('C').
  addE("R").property("ver","1").from('B').to('D').
  addE("R").property("ver","1").from('B').to('F')

我想提取一棵像这样的树:

A
  B (ver=2)
    D (ver=1)
    F (ver=1)
  C (ver=1) 

我的遍历查询重复问题:

g.V().has('name','A').
  repeat(
    outE('R').group().by(inV()).
    select(values).unfold().
    local(unfold().order().by('ver', desc).limit(1).inV())).
  times(3).
  emit().tree().toList()

结果:“减少障碍的父级不能重复()步:GroupStep([EdgeVertexStep(IN)],[FoldStep])”

在 Gremlify 上:https://gremlify.com/r3ubmv3gt8/4

非常感谢任何帮助。

谢谢, 安德鲁

问题是你不能以这种方式在 repeat 循环中使用 group(当与 emit 一起使用时),除非你使用副作用形式,其中group 被赋予了一个标签,例如 group('x')。考虑到这一点,您需要重构查询。

也许是这样的:

gremlin>   g.V().has('name','A').
......1>         repeat(map(outE('R').
......2>                    order().
......3>                      by('ver',desc).
......4>                    limit(1).
......5>                    inV())).
......6>         times(3).
......7>         emit().tree()

==>[v[61415]:[v[61417]:[v[61421]:[]]]]

或者,如果您知道最大深度,您可以删除 emit 并可能删除 tree 并只使用 path

gremlin>   g.V().has('name','A').
......1>         repeat(flatMap(outE('R').
......2>                    order().
......3>                      by('ver',desc).
......4>                    limit(1).
......5>                    inV())).
......6>         times(2).
......7>         path()

==>[v[61415],v[61417],v[61421]] 

最后,如果深度未知但你想设置一个上限,你可以稍微改变终止条件:

gremlin>   g.V().has('name','A').
......1>         repeat(flatMap(outE('R').
......2>                    order().
......3>                      by('ver',desc).
......4>                    limit(1).
......5>                    inV())).
......6>         until(__.not(out('R')).or().loops().is(3)).
......7>         path()

==>[v[61415],v[61417],v[61421]]  

更新 2022-01-03 添加:

根据评论和更新问题中提供的附加信息,我添加了一个附加示例。而不是 return a tree 这个查询 returns 一个新的 subgraph 表示遍历的结构,只有存在的任何两个相邻顶点之间的最高版本边缘。我使用 Gremlin 控制台来证明它有效。

gremlin> g.V().has('name','A').
......1>   repeat(outE('R').
......2>          group('x').
......3>            by(loops()).
......4>            by(group().
......5>                 by(inV()).
......6>                 by(order().by('ver',desc).limit(1))).inV()).
......7>   until(__.not(out())).
......8>   cap('x').unfold().select(values).unfold().select(values).subgraph('s').cap('s')   

==>tinkergraph[vertices:5 edges:4]  

我们可以为此 subgraph 创建一个新的 traversal 并探索它:

gremlin> g2=g.V().has('name','A').
......1>   repeat(outE('R').
......2>          group('x').
......3>            by(loops()).
......4>            by(group().
......5>                 by(inV()).
......6>                 by(order().by('ver',desc).limit(1))).inV()).
......7>   until(__.not(out())).
......8>   cap('x').unfold().select(values).unfold().select(values).subgraph('s').cap('s').next();[]

==>tinkergraph[vertices:5 edges:4]

gremlin> g3=g2.traversal()    


gremlin> g3.V().outE().inV().path().by('name').by('ver')
==>[A,2,B]
==>[A,1,C]
==>[B,1,F]
==>[B,1,D]


gremlin> g3.V().has('name','A').repeat(outE('R').inV()).until(__.not(out())).path().by('name').by('ver')
==>[A,1,C]
==>[A,2,B,1,F]
==>[A,2,B,1,D]   

进一步更新
在我发布上次更新后,我意识到使用 flatMap 的另一种方法可能会成功

gremlin> g.V().has('name','A').
......1>       repeat(
......2>         flatMap(
......3>           out().
......4>           dedup().
......5>           local(
......6>             inE().
......7>             order().
......8>               by('ver',desc).
......9>               limit(1))).
.....10>         inV()).
.....11>         until(__.not(out())).
.....12>         path().
.....13>           by('name').
.....14>           by('ver')   

==>[A,1,C]
==>[A,2,B,1,F]
==>[A,2,B,1,D]  

并生成 tree

gremlin> g.V().has('name','A').
......1>       repeat(
......2>         flatMap(
......3>           out().
......4>           dedup().
......5>           local(
......6>             inE().
......7>             order().
......8>               by('ver',desc).
......9>               limit(1))).
.....10>         inV()).
.....11>         until(__.not(out())).tree()
   
==>[v[0]:[e[13][0-R->2]:[v[2]:[e[16][2-R->10]:[v[10]:[]],e[15][2-R->6]:[v[6]:[]]]],e[14][0-R->4]:[v[4]:[]]]]