匿名遍历 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
代替 __
有效,那是巧合而不是设计,这意味着它将来有可能被破坏。
我已经阅读了关于匿名遍历的文档。我知道它们可以从 __
开始,并且可以在步进调制器中使用。虽然我在概念上不理解它。为什么我们不能在步进调制器中使用从图形遍历源生成的正常遍历?例如,在下面的 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
代替 __
有效,那是巧合而不是设计,这意味着它将来有可能被破坏。