有人可以解释一下 Gremlin 中的图遍历在做什么吗?

Can someone explain what this graph travesal in Gremlin is doing?

我在理解这些 Gremlin 查询时遇到了一些问题:

from os import getenv
from gremlin_python.structure.graph import Graph
from gremlin_python.process.graph_traversal import __
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
 pmap = g.V().has(name, value) \
                .union(__.hasLabel('UID'), 
                       __.hasLabel('OID').outE('attached').inV()) \
                .union(__.propertyMap(),
                       __.inE('attached').outV().hasLabel('OID') \
                                         .propertyMap()).toList()

所以我明白了 g.V().has(name, value) is looking for a vertex with the keyname = value. What is the union doing here? Is it unioning vertices with a label "OID" with edges that go outward with a label "attached"? What is theinV()` 以及为什么 union 的两个参数?

union() 步骤只是合并作为参数提供给它的子遍历流。举个更简单的例子:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has('person','name','marko').union(has('age',29),bothE())
==>v[1]
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> g.V().has('person','name','marko').union(has('age',30),bothE())
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]

在第一个示例中,我们得到 union() 以 "marko" 顶点作为 has('age',29)bothE() 的起点。由于 v[1] 也有一个值为“29”的 "age" 属性,我们在输出中看到 v[1]。我们还看到 v[1] 的所有边都合并到该输出流中。在第二次遍历中,我们看到 v[1] 被过滤掉了,因为 "age" 不等于“30”,所以我们得到的只是边缘。

考虑到这个解释,考虑一下您在问题中包含的遍历在做什么。它找到一个带有 "name" 的顶点和该键的某个值。这成为第一个 union() 的起点。如果顶点的标签为 "UID" 则它通过。如果顶点的标签为 "OID",则它遍历传出的 "attached" 边到相邻顶点和 returns 那些边。

奇怪的是 Vertex 只能有一个标签(至少根据 TinkerPop 的定义 - 一些图表支持多个元素标签)。因此,假设有一个标签,您实际上只能得到一个或另一个流。就个人而言,我认为 union() 的使用不是一个好的选择。我认为使用 coalesce 会更直观,因为只能返回一个流,因此从上面扩展了我的示例:

gremlin> g.V().has('person','name','marko').coalesce(has('age',30),has('age',29).bothE())
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> g.V().has('person','name','marko').coalesce(has('age',29),has('age',29).bothE())
==>v[1]

在我看来,coalesce() 的使用使意图更加清晰。继续原始代码到第二个 union() - 此时,您要么拥有原始 Vertex 或一个或多个 "attached" 顶点,其遍历结合了 propertyMap() and/or propertyMap() 个额外 "attached" 个具有 "OID" 标签的顶点。

根据所提供的信息,很难确切地说出这种遍历的意图。根据数据结构是什么以及意图是什么,我想事情可以简化。希望我至少已经解释了 union() 在做什么,并为您澄清了这一点,因为这似乎是您问题的核心。