【问题标题】:Janusgraph Remote Traversal with Java使用 Java 进行 Janusgraph 远程遍历
【发布时间】:2020-12-29 02:21:05
【问题描述】:

我正在构建一个需要连接到远程 JanusGraph 服务器并动态创建图表的 Java 应用程序。

我已经安装/配置了一个带有 Berkeley 数据库后端和 ConfigurationManagementGraph 支持的单节点 JanusGraph 服务器,以便我可以在服务器上创建/管理多个图表。

Gremlin 控制台中,我可以连接到远程服务器、创建图形、创建顶点等。示例:

gremlin> :remote connect tinkerpop.server conf/remote.yaml session
gremlin> :remote console

gremlin> map = new HashMap<String, Object>();
gremlin> map.put("storage.backend", "berkeleyje");
gremlin> map.put("storage.directory", "db/test");
gremlin> ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));
gremlin> ConfiguredGraphFactory.create("test");

gremlin> graph = ConfiguredGraphFactory.open("test");
gremlin> g = graph.traversal();
gremlin> g.addV("person").property("name", "peter");
gremlin> g.tx().commit();
gremlin> graph.vertices().size();
==>1
gremlin> g.V();
==>v[4288]
gremlin> g.V().count();
==>1
gremlin> g.close();

到目前为止一切顺利。在 Java 端,我可以连接到远程服务器并通过 Client.submit() 方法发出命令。在以下示例中,我连接到远程服务器并创建一个名为“test2”的新图形:

Cluster cluster = Cluster.build()
    .addContactPoint(host)
    .port(port)
    .serializer(Serializers.GRYO_V3D0)
    .create();

String name = "test2";

String sessionId = UUID.randomUUID().toString();
Client client = cluster.connect(sessionId);
client.submit("map = new HashMap<String, Object>();");
client.submit("map.put(\"storage.backend\", \"berkeleyje\");");
client.submit("map.put(\"storage.directory\", \"db/" + name + "\");");
client.submit("ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));");
client.submit("ConfiguredGraphFactory.create(\"" + name + "\");");

我可以确认该图表已创建,并使用 client.submit() 方法以编程方式查看其他图表:

ResultSet results = client.submit("ConfiguredGraphFactory.getGraphNames()");
Iterator<Result> it = results.iterator();
while (it.hasNext()){
    Result result = it.next();
    String graphName = result.getString();
    System.out.println(graphName);
}

接下来我想连接到一个图形并以编程方式遍历节点(在 Java 中)。但是,我似乎无法弄清楚如何做到这一点。根据我的阅读,它应该是这样简单的:

DriverRemoteConnection conn = DriverRemoteConnection.using(client, name); //"_traversal"
GraphTraversalSource g = AnonymousTraversalSource.traversal().withRemote(conn);

这些命令不会引发任何错误,但 GraphTraversalSource 似乎为空:

System.out.println(g.getGraph()); //always returns emptygraph[empty]
System.out.prinltn(g.V()); //Appears to be empty [GraphStep(vertex,[])]
Iterator<Vertex> it = g.getGraph().vertices(); //empty

关于如何在 Java 中为远程 JanusGraph 服务器获取 GraphTraversalSource 的任何建议?我怀疑我的问题与 ConfigurationManagementGraph 有关,但我无法解决。再次,client.submit() 有效。如果我能做这样的事情会很酷:

GraphTraversalSource g = (GraphTraversalSource) client.submit("ConfiguredGraphFactory.open(\"" + name + "\");").iterator().next();

...但是当然,那是行不通的

更新

查看代码,似乎传递给 DriverRemoteConnection 的图形名称 (remoteTraversalSourceName) 被忽略了。

从 DriverRemoteConnection 开始:

DriverRemoteConnection conn = DriverRemoteConnection.using(client, name); 

在底层,图名称 (remoteTraversalSourceName) 仅用于设置别名(例如 client.alias(name);)

接下来,在 AnonymousTraversalSource.traversal().withRemote() 方法中

GraphTraversalSource g = AnonymousTraversalSource.traversal().withRemote(conn);

在后台,withRemote() 正在调用:

traversalSourceClass.getConstructor(RemoteConnection.class).newInstance(remoteConnection);

其中 traversalSourceClass 是 GraphTraversalSource.class

与此相同:

g = GraphTraversalSource.class.getConstructor(RemoteConnection.class).newInstance(conn);

最后,GraphTraversalSource 的构造函数如下所示:

public GraphTraversalSource(final RemoteConnection connection) {
    this(EmptyGraph.instance(), TraversalStrategies.GlobalCache.getStrategies(EmptyGraph.class).clone());
    this.connection = connection;
    this.strategies.addStrategies(new RemoteStrategy(connection));
}

如您所见,GraphTraversalSource 中的图形变量从未设置过。

我怀疑 (a) 我不应该使用 AnonymousTraversalSource 或 (b) 我需要以其他方式实例化 GraphTraversalSource,可能使用 Graph 对象。

【问题讨论】:

    标签: java gremlin janusgraph


    【解决方案1】:

    更新答案

    您使用的通道器很可能是 Tinkerpop 的通道器 org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer。用 Janus 的通道器 org.janusgraph.channelizers.JanusGraphWsAndHttpChannelizer 替换它可以正确地将图绑定到连接。

    旧答案

    当通道器为org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer 时使用的解决方法。

    我也有同样的问题。目前,我发现的解决方法是在 Janus 启动期间绑定遍历。 除了gremlin-server.yaml and janusgraph.properties,我还用以下内容覆盖了empty-sample.groovy

    def globals = [:]
    ConfiguredGraphFactory.getGraphNames().each { name ->
      globals << [ (name + "_traversal") : ConfiguredGraphFactory.open(name).traversal()]
    }
    

    现在您创建的图表可在yourgraphname_traversal 获得:

    import org.apache.tinkerpop.gremlin.driver.Cluster
    import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection
    import org.apache.tinkerpop.gremlin.driver.ser.Serializers
    import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource
    ...
      val cluster = Cluster.build()
        .addContactPoint("your_load_balancer_host")
        .port(8182)
        .serializer(Serializers.GRAPHBINARY_V1D0.simpleInstance())
        .create()
      val remoteConnection = DriverRemoteConnection.using(cluster, "yourgraphname_traversal")
      val g = AnonymousTraversalSource.traversal().withRemote(remoteConnection)
    

    解决方案并不理想,因为它需要重新启动所有 Janus 节点才能更新绑定。假设图表很少被创建,这个解决方案至少是一些东西。

    【讨论】:

      猜你喜欢
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多