我有一些代码可以根据用户提供的查询图动态生成gremlin遍历。它产生的gremlin很大程度上依赖于回溯。我发现一些生成gremlin的边缘情况并没有达到我的预期,但我也无法在网上找到有关这些管道使用规则的规则(如'as'和'back) ' 在这种情况下)。其中一个边缘情况的示例:
g.V("id", "some id").as('1').inE("edgetype").outV.has("@class", "vertextype").as('2').inE("edgetype").outV.has("@class", "vertextype").filter{(it.getProperty("name") == "Bob")}.outE("edgetype").as('target').inV.has("id", "some id").back('2').outE("edgetype").inV.has("id", "some other id").back('target')
遍历的目标是返回'与'目标'相同的边缘。当我针对我的orientdb数据库运行它时,它遇到一个空异常。我将异常缩小到遍历中的最后一个管道:back('target')。我猜测'as'和'后退的顺序很重要,而as('target')在执行后('2')后就会超出范围。所以有几个问题:
我的理解(那个'目标'是否超出了范围,因为我在'as'd之前回溯'是正确的?)
我是否可以在任何地方学习围绕回溯的规则,而无需对gremlin源进行逆向工程?
编辑: 我找到了相关的源代码:
public static List<Pipe> removePreviousPipes(final Pipeline pipeline, final String namedStep) {
final List<Pipe> previousPipes = new ArrayList<Pipe>();
for (int i = pipeline.size() - 1; i >= 0; i--) {
final Pipe pipe = pipeline.get(i);
if (pipe instanceof AsPipe && ((AsPipe) pipe).getName().equals(namedStep)) {
break;
} else {
previousPipes.add(0, pipe);
}
}
for (int i = 0; i < previousPipes.size(); i++) {
pipeline.remove(pipeline.size() - 1);
}
if (pipeline.size() == 1)
pipeline.setStarts(pipeline.getStarts());
return previousPipes;
}
看起来BackFilterPipe不会删除后管和命名为管道之间的任何aspipe,但它们必须对BackFilterPipe外部的管道不可见。我想我的生成代码的算法必须更聪明地检测目标何时在元管道中。
答案 0 :(得分:0)
原来我使用的方式&#39; as&#39;和&#39;回来&#39;毫无意义。当你考虑到&#39; back(&#39; 2&#39;)&#39;之间的所有内容时。和&#39; as(&#39; 2&#39;)&#39;它包含在BackFilterPipe的内部管道中,很明显,元管道不能像这样重叠:as(&#39; 2&#39;)as(&#39; target&#39; ),返回(&#39; 2&#39;),返回(&#39;目标&#39;)。