简体   繁体   English

Gremlin图遍历回溯

[英]Gremlin graph traversal backtracking

I have some code that generates gremlin traversals dynamically based on a query graph that a user supplies. 我有一些代码可根据用户提供的查询图动态生成gremlin遍历。 It generates gremlin that relies heavily on backtracking. 它生成的gremlin很大程度上依赖于回溯。 I've found some edge cases that are generating gremlin that doesn't do what I expected it to, but I also can't find anything online about the rules surrounding the usage of some of these pipes (like 'as' and 'back' in this case). 我发现一些生成gremlin的边缘案例无法达到我的预期,但是我也无法在线找到有关这些管道的使用规则的任何信息(例如“ as”和“ back” ' 在这种情况下)。 An example of one of these edge cases: 这些极端情况之一的示例:

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')

The goal of the traversal is to return the edges that were 'as'd as 'target'. 遍历的目标是返回“与目标一样”的边。 When I run this against my orientdb database it encounters a null exception. 当我对我的orientdb数据库运行它时,它遇到一个null异常。 I narrowed down the exception to the final pipe in the traversal: back('target'). 我将异常范围缩小到遍历中的最后一个管道:back('target')。 I'm guessing that the order of the 'as's and 'back's matters and that the as('target') went 'out of scope' as soon as back('2') was executed. 我猜测'as和'back'的顺序很重要,而as('target')在执行back('2')后就变得'超出范围'。 So a few questions: 有几个问题:

Is my understanding (that 'target' goes out of scope because I backtracked to before it was 'as'd) correct? 我的理解(该“目标”超出范围是因为我在“按原样”之前回溯到了)是否正确?

Is there anywhere I can learn the rules surrounding backtracking without having to reverse engineer the gremlin source? 有什么地方我可以学习回溯规则,而无需对gremlin来源进行反向工程?

edit: I found the relevant source code: 编辑:我找到了相关的源代码:

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;
}

It looks like the BackFilterPipe does not remove any of the aspipes between the back pipe and the named as pipe, but they must not be visible to pipes outside the BackFilterPipe. 看起来BackFilterPipe不会删除后管和命名管道之间的任何aspipe,但是对于BackFilterPipe之外的管道,它们必须不可见。 I guess my algorithm for generating the code is going to have to be smarter about detecting when the target is within a meta pipe. 我想我生成代码的算法在检测目标何时位于元管道中时必须变得更加聪明。

Turns out the way I was using 'as' and 'back' made no sense. 原来我使用“ as”和“ back”的方式没有任何意义。 When you consider that everything between the 'back('2')' and the 'as('2')' is contained within the BackFilterPipe's inner pipeline, it becomes clear that meta pipes can't be overlapped like this: as('2'), as('target'), back('2'), back('target'). 当您考虑到'back('2')'和'as('2')'之间的所有内容都包含在BackFilterPipe的内部管道中时,很明显,元管道不能像这样重叠:as(' 2'),as('target'),back('2'),back('target')。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM