1

当我在 Java 中使用 gremlin-driver 使用 gremlin-server 连接时,我无法使用 GraphTraversal 的“sideEffect”。

graph = EmptyGraph.instance()
cluster = Cluster.open("conf/remote-objects.yaml");
graphTraversalSource = graph.traversal().withRemote(DriverRemoteConnection.using(cluster));

我使用 sideEffect 的查询如下所示:

AtomicLong level1 = new AtomicLong(0);    
graphTraversalSource.V().hasLabel("user")
            .has("uuid", "1234")
            .sideEffect(it -> it.get().property("level", level1.getAndIncrement())).emit().repeat(in())
            .until(loops().is(5)).valueMap("uuid", "name", "level");

当我使用 janusgraph-dynamodb-storage-backend 作为依赖项并在 Java 应用程序中运行 gremlin 服务器并连接到 dyamodb 时,此查询曾经有效。当我切换到使用远程连接到 EC2 中运行的 gremlin 服务器时,我开始收到以下错误消息:

java.util.concurrent.CompletionException: io.netty.handler.codec.EncoderException: WebSocketGremlinRequestEncoder must produce at least one message., took 3.895 sec

如果我从上面的查询中删除 sideEffect 部分,它工作正常。我真的需要在遍历期间添加一个自定义属性并将其包含在结果中而不将其保存在数据库中。

4

1 回答 1

0

你有几个问题。第一个问题是您试图远程将 Lambda 中的 lambdasideEffect()无法序列化为 Gremlin 字节码 - 至少不是您提供的形式。但是,您可以这样做:

gremlin> cluster = Cluster.open("conf/remote-objects.yaml")
==>localhost/127.0.0.1:8182
gremlin> g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster))
==>graphtraversalsource[emptygraph[empty], standard]
gremlin> g.addV('person').as('p').addE('link').to('p')
==>e[1][0-link->0]
gremlin> g.V().sideEffect(Lambda.function("it.get().property('level',1)")).valueMap()
==>[level:[1]]

请注意,我必须导入import org.apache.tinkerpop.gremlin.util.function.*控制台才能使最后一行在那里工作 - 这将在 3.2.7/3.3.0 中修复。

所以,你可以通过这种方式传递你的 lambda,但是:

  1. 我认为您的遍历不会像以前那样工作,因为您正在引用客户端本地的变量level1- 服务器对此一无所知。
  2. TinkerPop 通常建议您避免使用 lambda。

我不太了解您的 Gremlin 正在做什么来提供有关如何解决此问题的建议。你确实给出了这个提示:

我真的需要在遍历期间添加一个自定义属性并将其包含在结果中而不将其保存在数据库中。

...但是上面的 Gremlin 确实将值写入level1数据库,所以我不确定你在追求什么。

于 2017-09-14T10:49:22.367 回答