【问题标题】:Why does this Gremlin traversal return empty?为什么这个 Gremlin 遍历返回空?
【发布时间】:2021-04-23 11:05:00
【问题描述】:

我有一个 Gremlin 顶点,它具有设置值属性 emailsphones。作为我的更新逻辑的一部分,我正在尝试删除并重新创建这些属性:

String key = ThreadLocalRandom.current().nextInt()
def dropped = vtx.as(key).properties('emails', 'phones').drop().<Vertex>select(key)

我的期望是顶点将被as标记,然后我遍历属性并删除它们,然后使用select返回顶点进行进一步处理。但是,执行此操作总是会导致空遍历。

我已经能够让遍历返回一个结果,而不是说

def dropped = vtx.sideEffect(__.properties('emails', 'phones').drop())

但我想确保在继续之前严格删除这些属性,然后我会继续重新插入它们。

为什么原始遍历的行为不像我预期的那样?对于sideEffect 版本,是否需要添加barrier() 以确保正确性,如果需要,是否足够?

【问题讨论】:

  • String key = ... nextInt () 可以吗?
  • @daggett 它在 Groovy 中用于分配给 String。

标签: java groovy gremlin tinkerpop3


【解决方案1】:

请注意,drop() 是一个过滤步骤,因此它不会产生遍历器。进入其中的所有内容都将从流中删除。这样,您的select() 永远不会被调用。您可以通过profile() 看到这一点:

gremlin> g.V().as('a').drop().select('a').profile()
==>Traversal Metrics
Step                                                               Count  Traversers       Time (ms)    % Dur
=============================================================================================================
TinkerGraphStep(vertex,[])@[a]                                       808         808           1.922    19.04
DropStep                                                                                       8.138    80.60
SelectOneStep(last,a)                                                                          0.010     0.10
NoOpBarrierStep(2500)                                                                          0.026     0.26
                                            >TOTAL                     -           -          10.097        -

您使用sideEffect() 的方法是做您想做的事情的正确方法。副作用遍历应该在继续之前迭代完成,因此我希望当 sideEffect() 步骤完成时,遍历器通过它时会删除所有属性。

【讨论】:

  • 好的,我会转换过来的。不过,这是一个非常令人惊讶的设计选择,可以说 某些 减少为空输出的操作可以通过 select 恢复,但其他操作则不能。
  • 你的意思是“空列表”作为“空输出”的例子吗?
  • 不是故意的,但我可能没有意识到某些表达式中“空列表”和“遍历中没有项目”之间的区别。 (有没有办法以编程方式运行profile() 作为副作用,打印输出并仍然返回结果?API 有一个签名可能意味着这个,但我不知道如何使用它。如果是,我会在上面发布一个新问题。)
  • g.inject() 在遍历中没有项目,但 g.inject().fold() 会产生一个空列表,因为 Gremlin 将“无遍历器”减少为空的 List 对象。我想这就是您提到“某些操作”时的含义。如果是这样,我会说当您考虑流中的遍历器而不是它们所持有的对象时更有意义。您不能profile() 并同时获得结果,直到完成:issues.apache.org/jira/browse/TINKERPOP-2459
  • 也许,换一种说法,一个没有对象的遍历器仍在流中移动,但是一个“死”/过滤掉的遍历器不能触发下游操作。
猜你喜欢
  • 2021-12-26
  • 2019-11-17
  • 1970-01-01
  • 2018-09-02
  • 1970-01-01
  • 2021-12-21
  • 2022-12-03
  • 2021-04-27
  • 2023-01-15
相关资源
最近更新 更多