格林姆林-在一次遍历中移动多个边

时间:2019-11-06 16:42:07

标签: graph-databases gremlin amazon-neptune

我正在使用Gremlin访问AWS Neptune中的数据。我需要修改从单个顶点引出的2条边,以指向2个与当前指向的顶点不同的顶点。

例如,如果当前关系如下所示:

(X)---(A)---(Y)
   (B)   (C)

我希望将其修改为:

(X)   (A)   (Y)
     /   \
   (B)   (C)

为确保整个操作在单个事务中完成,我需要在单个遍历中完成此操作(因为在AWS Neptune中为manual transaction logic using tx.commit() and tx.rollback() is not supported)。

我尝试了以下查询来完成此操作,但失败了:

1)添加新的边,并通过使用别名选择它们来放下之前的边:

g.V(<id of B>).as('B').V(<id of C>).as('C').V(<id of A>).as('A').outE('LINK1','LINK2')
.as('oldEdges').addE('LINK1').from('A').to('B').addE('LINK2').from('A').to('C')
.select('oldEdges').drop();

在这里,由于outE('LINK1','LINK2')返回2条边,因此在其后添加的边执行两次。因此,我得到的A到B和C之间的预期边数是原来的两倍。

2)添加新边缘,并删除边缘id不等于新添加边缘的现有边缘。

g.V(<id of B>).as('B').V(<id of C>).as('C').V(<id of A>).as('A')
.addE('LINK1').from('A').to('B').as('edge1').addE('LINK2').from('A').to('C').as('edge2')
.select('A').outE().where(__.hasId(neq(select('edge1').id()))
.and(hasId(neq(select('edge2').id())))).drop();

在这里,我的gremlin控制台出现以下异常:

could not be serialized by org.apache.tinkerpop.gremlin.driver.ser.AbstractGryoMessageSerializerV3d0. java.lang.IllegalArgumentException: Class is not registered: org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal Note: To register this class use: kryo.register(org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal.class); at org.apache.tinkerpop.shaded.kryo.Kryo.getRegistration(Kryo.java:488) at org.apache.tinkerpop.gremlin.structure.io.gryo.AbstractGryoClassResolver.writeClass(AbstractGryoClassResolver.java:110) at org.apache.tinkerpop.shaded.kryo.Kryo.writeClass(Kryo.java:517) at org.apache.tinkerpop.shaded.kryo.Kryo.writeClassAndObject(Kryo.java:622) at org.apache.tinkerpop.gremlin.structure.io.gryo.kryoshim.shaded.ShadedKryoAdapter.writeClassAndObject(ShadedKryoAdapter.java:49) at org.apache.tinkerpop.gremlin.structure.io.gryo.kryoshim.shaded.ShadedKryoAdapter.writeClassAndObject(ShadedKryoAdapter.java:24) ...

请帮助。

1 个答案:

答案 0 :(得分:0)

您可以尝试:

g.V(<id of A>).union(
    addE('Link1').to(V(<id of B>)),
    addE('Link2').to(V(<id of C>)),
    outE('Link1', 'Link2').where(inV().hasId(<id of X>,<id of Y>)).drop()
)