traversal.asAdmin().addStep(step) 用于远程调用

traversal.asAdmin().addStep(step) for remote calls

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

下面遍历returns由标签"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();

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

在这两种情况下,t.toString() returns

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

我做错了什么?

我认为您不需要使用任何 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 传递给需要用新步骤对其进行变异的函数似乎更自然。您可能还会发现 this information 关于遍历重用的帮助。