我正在尝试使用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)])]
我在做什么错了?
答案 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很有帮助。