Gremlin - 顶点的 Upsert 不适用于合并

Gremlin - Upsert of vertex not working with coalesce

我是 gremlin 的新手,有一个非常简单的案例需要检查:

我为此使用 Java API。

我的代码:

g.V().hasLabel("Entity").has("identifier", "123").fold()
.coalesce(
    __.unfold(),
    __.addV("Entity")
        .property("identifier", "123")
        .property("value", "A")
        .property("action", "add")
    )
.property("value", "A")
.property("action", "update")
.iterate();

我知道这是一个非常简单的案例,我参考了 [

中给出的示例

但是没用。如果顶点不存在,则添加属性,但属性也会更新。

当您编写 Gremlin 时,您需要从流的角度来思考。 V() 生成图中所有顶点的流。设想该流中的每个项目命中 hasLabel()has() 过滤器将被配对,直到它们命中 fold() 的减少步骤,这会产生一个 List 与匹配过滤条件的顶点或者,如果有 none,它会简单地生成一个空列表,该列表成为流中的新对象。

从那里 coalesce() 产生一种 if-then 类型的情况,其中第一个子流提供给它 returns 一个值最终被耗尽,其余的子流被忽略。因此,如果 unfold()Listfold() 产生的顶点包含一个顶点,那么它被提供给流并且该顶点存在并且 coalesce() 从而产生现有的顶点并继续 property("value", "A").property("action", "update") 的最后两个步骤。如果 List 为空,则 unfold() 流不产生任何对象并转到下一个以 addV() 开头的子流。 addV() 流显然会产生一个具有指定属性的新 Vertex,但是随后 coalesce() 作为其父级将产生新添加的顶点到流中,它也将继续到最后两个步骤,从而覆盖您提供给 addV().

的 属性 值

如果你想有两条独立的路径,那么你可以这样做:

g.V().hasLabel("Entity").has("identifier", "123").fold()
.coalesce((Traversal)
    __.unfold()
        .property("value", "A")
        .property("action", "update"),
    __.addV("Entity")
        .property("identifier", "123")
        .property("value", "A")
        .property("action", "add")
    )
.iterate();

无论顶点是否存在,合并都会 return 现有顶点或新创建的顶点。在任何一种情况下,合并后的 属性 设置步骤将应用于从中流出的任何内容。如果您只想将合并后的更改应用于现有顶点,请将它们放在展开步骤之后。