【问题标题】:Gremlin graph traversal backtrackingGremlin 图遍历回溯
【发布时间】:2023-12-16 15:02:01
【问题描述】:

我有一些代码可以根据用户提供的查询图动态生成 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')

遍历的目标是返回'as'd as'd as 'target'的边。当我对我的 orientdb 数据库运行它时,它遇到了一个空异常。我将异常缩小到遍历中的最后一个管道:back('target')。我猜 'as's 和 'back' 的顺序很重要,并且 as('target') 一旦执行 back('2') 就“超出范围”。所以有几个问题:

我的理解(“目标”超出范围是因为我回溯到它之前的“原样”)正确吗?

有没有什么地方可以学习回溯规则,而无需对 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 外部的管道可见。我想我的代码生成算法必须更智能地检测目标何时位于元管道内。

【问题讨论】:

    标签: graph orientdb traversal backtracking gremlin


    【解决方案1】:

    原来我使用“as”和“back”的方式毫无意义。当您考虑到 'back('2')' 和 'as('2')' 之间的所有内容都包含在 BackFilterPipe 的内部管道中时,很明显元管道不能像这样重叠:as(' 2'), as('target'), back('2'), back('target').

    【讨论】: