【发布时间】: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