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

时间:2018-12-04 23:21:58

标签: gremlin tinkerpop janusgraph gremlin-server

我正在尝试使用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)])]

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

我认为您不需要使用任何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很有帮助。