匿名遍历 vs 普通遍历 gremlin

Anonymous traversal vs normal traversal gremlin

我已经阅读了关于匿名遍历的文档。我知道它们可以从 __ 开始,并且可以在步进调制器中使用。虽然我在概念上不理解它。为什么我们不能在步进调制器中使用从图形遍历源生成的正常遍历?例如,在下面的 gremlin 代码中创建一个 edge

        this.g
            .V(fromId) // get vertex of id given for the source
            .as("fromVertex") // label as fromVertex to be accessed later
            .V(toId) // get  vertex of id given for destination
            .coalesce( // evaluates the provided traversals in order and returns the first traversal that emits at least one element
                inE(label) // check incoming edge of label given
                    .where( // conditional check to check if edge exists
                        outV() // get destination vertex of the edge to check
                            .as("fromVertex")), // against staged vertex
                addE(label) // add edge if not present
                    .property(T.id, id) // with given id
                    .from("fromVertex")) // from source vertexx
            .next(); // end traversal to commit to graph

为什么 __.inE()__.addE() 是匿名的?为什么我们不能写 this.g.inE()this.g.addE() 呢?无论哪种方式,编译器都不会抱怨。那么匿名遍历在这里给我们带来了什么特殊的好处呢?

tldr;请注意,在 3.5.0 中,用户无法使用从 GraphTraversalSource 生成的遍历,并且必须使用 __,因此您可以期望在最新版本中强制执行此操作。

从历史上讲更多....

A GraphTraversalSource,您的 g,旨在从分配源配置的开始步骤产生新的遍历。匿名遍历意味着在生成“空白”时采用分配给它的 parent 遍历的内部配置。虽然从 g 产生的遍历可以覆盖其内部配置,但当分配给 parent 时,它并不是设计的一部分,因为它始终以这种方式工作,所以你抓住机会依靠这种行为。

另一点是,从 Gremlin 步骤的完整列表中,只有少数实际上是“开始步骤”(即 addV()addE()inject()V(), E()) 因此在构建 child 遍历时,您实际上只能使用这些选项。由于您经常需要访问完整的 Gremlin 步骤列表来启动 child 遍历参数,因此最好简单地选择 __。通过与这个约定保持一致,它可以防止混淆为什么 child 遍历“有时以 g 开始,而其他时候以 __ 开始”,如果它们在单个遍历中可互换使用。

可能还有其他技术原因需要 __。可以在以下 Gremlin 控制台代码段中演示一个不需要大量解释的容易看到的内容:

gremlin> __.addV('person').steps[0].class
==>class org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep
gremlin> g.addV('person').steps[0].class
==>class org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep

这两个遍历不会产生类似的步骤。如果今天使用 g 代替 __ 有效,那是巧合而不是设计,这意味着它将来有可能被破坏。