简体   繁体   中英

Gremlin graph traversal backtracking

I have some code that generates gremlin traversals dynamically based on a query graph that a user supplies. It generates gremlin that relies heavily on backtracking. 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). 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. I narrowed down the exception to the final pipe in the traversal: 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. 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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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