在树查询中重复遍历有序边的问题
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]:[]]]]
我有一个图,其中一个顶点有来自同一父项的多条边。我只需要根据最高 属性 值遍历一条边来创建一棵树。
我使用“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]:[]]]]