Gremlin图遍历回溯

时间:2016-03-15 22:07:57

标签: graph orientdb traversal backtracking gremlin

我有一些代码可以根据用户提供的查询图动态生成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外部的管道不可见。我想我的生成代码的算法必须更聪明地检测目标何时在元管道中。

1 个答案:

答案 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;)。