sack() 步骤中的合并运算符无法按预期工作

问题描述 投票:0回答:1

我一直在与

sack()
一起工作
gremlin
。当两个遍历器合并时,我试图对 sack 执行一些操作。但由于某种原因,合并似乎没有按预期进行。为了描述我的问题,我创建了一个示例图。

重现图表的步骤

g.addE("causes").from(coalesce(V().has("Name","m1"),addV().property("Name","m1"))).to(coalesce(V().has("Name","m2"),addV().property("Name","m2")));
g.addE("causes").from(coalesce(V().has("Name","m1"),addV().property("Name","m1"))).to(coalesce(V().has("Name","m3"),addV().property("Name","m3")));
g.addE("causes").from(coalesce(V().has("Name","m1"),addV().property("Name","m1"))).to(coalesce(V().has("Name","m4"),addV().property("Name","m4")));
g.addE("causes").from(coalesce(V().has("Name","m2"),addV().property("Name","m2"))).to(coalesce(V().has("Name","m5"),addV().property("Name","m5")));
g.addE("causes").from(coalesce(V().has("Name","m2"),addV().property("Name","m2"))).to(coalesce(V().has("Name","m6"),addV().property("Name","m6")));
g.addE("causes").from(coalesce(V().has("Name","m3"),addV().property("Name","m3"))).to(coalesce(V().has("Name","m7"),addV().property("Name","m7")));
g.addE("causes").from(coalesce(V().has("Name","m3"),addV().property("Name","m3"))).to(coalesce(V().has("Name","m8"),addV().property("Name","m8")));
g.addE("causes").from(coalesce(V().has("Name","m6"),addV().property("Name","m6"))).to(coalesce(V().has("Name","m9"),addV().property("Name","m9")));
g.addE("causes").from(coalesce(V().has("Name","m7"),addV().property("Name","m7"))).to(coalesce(V().has("Name","m9"),addV().property("Name","m9")));
g.addE("causes").from(coalesce(V().has("Name","m9"),addV().property("Name","m9"))).to(coalesce(V().has("Name","m10"),addV().property("Name","m10")));

我使用 sack 来计算遍历的深度,当两个遍历器相遇时,我使用

minus
作为 sack 合并运算符。

我使用了以下查询,同时从顶点

m2
m3
开始遍历。

gremlin> g.V().has("Name","m2").id();
==>4200
gremlin> g.V().has("Name","m3").id();
==>4208
gremlin> g.withSack(0,minus).V(4200,4208).repeat(optional(outE().sack(sum).by(constant(1)).inV())).as('endnode').times(10).sack().group().by(select('endnode').values('Name')).unfold();
==>m5=[1]
==>m8=[1]
==>m10=[3, 3]

预期结果应该是

m10=[1, 1]
,但它是
m10=[3, 3]
。似乎合并操作没有被触发。

我尝试了相同的查询,但来自 Vertex

m1

gremlin> g.V().has("Name","m1").id();
==>4256
gremlin> g.withSack(0,minus).V(4256).repeat(optional(outE().sack(sum).by(constant(1)).inV())).as('endnode').times(10).sack().group().by(select('endnode').values('Name')).unfold();
==>m4=[1]
==>m5=[2]
==>m8=[2]
==>m10=[1, 1]

这样,我得到了预期的结果

m10=[1, 1]
。合并运算符正在被触发。

我并不是想用 sack 执行精确的操作。我用这个例子只是为了描述我的问题。实际的麻袋操作稍微复杂一些,但我能够重现同样的问题。

是否还需要包含其他一些东西才能完成这项工作?

提前致谢。

java gremlin janusgraph gremlinpython gremlin-java
1个回答
0
投票

看起来 m2+m3 启动示例和仅 m1 启动之间有一个关键区别。

当你只从 m1 开始时,如:

gremlin> g.V().has("Name","m1").id();
==>4256
gremlin> g.withSack(0,minus).V(4256).repeat(optional(outE().sack(sum).by(constant(1)).inV())).as('endnode').times(10).sack().group().by(select('endnode').values('Name')).unfold();

只有 1 个遍历器进入重复,在这种情况下,当两条路径都到达 m9 时,合并发生在重复内。此时,两个囊的值为 3,减去该值后,每个囊的值为 0。然后,当它们移动到 m10 时,它们都会递增,得到 [1, 1]。

在 2 个起点示例中:

gremlin> g.V().has("Name","m2").id();
==>4200
gremlin> g.V().has("Name","m3").id();
==>4208
gremlin> g.withSack(0,minus).V(4200,4208).repeat(optional(outE().sack(sum).by(constant(1)).inV())).as('endnode').times(10).sack().group().by(select('endnode').values('Name')).unfold();

有 2 个不同的遍历器进入重复。每个重复调用都彼此独立运行,并且每个调用之间没有批量/合并。在这种情况下,repeat 的“m2”调用完整运行,发现从 m2 到 m10 的距离为 3。然后“m3”调用运行,发现从 m3 到 m10 的距离也是 3。然后这 2 个 sac都被访问并分组形成 [3, 3]。您可以通过在重复后添加

barrier()
步骤来强制退出重复的 2 m10 遍历器进行批量处理。这会在重复后将 2 个 3 合并为 0。

gremlin> g.withSack(0,minus).V(4200,4208).repeat(optional(outE().sack(sum).by(constant(1)).inV())).as('endnode').times(10).barrier().sack().group().by(select('endnode').values('Name')).unfold();
==>m5=[1]
==>m8=[1]
==>m10=[0, 0]

在我看来,预计重复的单独迭代之间不会出现批量/合并。在 gremlin 中,子遍历的每次执行通常是相互独立的。

© www.soinside.com 2019 - 2024. All rights reserved.