首页 > 解决方案 > traversal.asAdmin().addStep(step) 用于远程调用

问题描述

我正在尝试使用 Java 客户端到远程 JanusGraph 服务器构建复杂的遍历。

以下遍历返回由标签“mylabel”标识的 ReferenceVertex 元素:

GraphTraversal<Vertex, Vertex> t = g.V().hasLabel("mylabel");
List<Vertex> r = t.toList();

对于更复杂的查询,我需要连接构成整个查询一部分的多个遍历。下面的代码说明了这个概念:

GraphTraversal<Vertex, Vertex> addMe = __.hasLabel("mylabel");
GraphTraversal<Vertex, Vertex> t = g.V();
for (Step<?, ?> step : addMe.asAdmin().getSteps()) {
     t.asAdmin().addStep(step);
}
List<Vertex> r = t.toList();

对于本地访问,这是可行的。然而,对于远程访问,它返回服务器上所有可用的顶点,而不是标签标识的顶点。

在这两种情况下, t.toString() 都会返回

[GraphStep(vertex,[]), HasStep([~label.eq(mylabel)])]

我究竟做错了什么?

标签: gremlintinkerpopjanusgraphgremlin-server

解决方案


我不认为你需要进入任何asAdmin()方法。与其构建匿名遍历来尝试附加到父遍历,我认为最好只传递父GraphTraversal实例并根据需要简单地添加步骤:

private static GraphTraversal addFilters(GraphTraversal t) {
    return t.hasLabel("mylabel");
}

...

GraphTraversal<Vertex, Vertex> t = g.V();
t = addFilters(t);
List<Vertex> r = t.toList();

您的方法不适用于远程遍历是有原因的,这与 Gremlin 字节码在幕后的构造方式有关。使用这些asAdmin()方法绕过了一些内部工作,并且遍历的那些部分不会发送到服务器 - 无论如何这是一种简单的解释方式。如果您绝对必须以这种方式构造遍历的匿名部分,然后以这种确切的方式附加它们,那么我想我会这样做:

GraphTraversal<Vertex, Vertex> addMe = __.hasLabel("mylabel");
GraphTraversal<Vertex, Vertex> t = g.V();
List<Vertex> r = t.filter(addMe).toList();

我不是特别喜欢这种方法,因为根据你在做什么,你可以欺骗优化你的遍历的 JanusGraph 遍历策略,你会失去一些性能优化。我也不太喜欢这种风格 - 将 传递GraphTraversal给需要用新步骤改变它的函数似乎更自然。您可能还会发现有关遍历重用的这些信息很有帮助。


推荐阅读