将filterVertice UDF从ArangoDB 2.8迁移到ArangoDB 3

gcxthw6b  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(103)

我目前正在将TRAVERSAL函数从arangoDB 2迁移到arangoDB 3。aql有一个自定义的leaf访问器和一个filterVertices选项,该选项带有一个自定义的AQL函数(用于更具体的过滤)。

FOR result IN TRAVERSAL(
    page, 
    menu, 
    "page/99999999999999",
    "inbound",
    {filterVertices : "udf::customFilter", visitor : "udf::customVisitor", }
 ) RETURN result

leaf visitor UDF相对容易转移,因为它只是创建一个自定义对象,但我在使用filterVertices UDF时遇到了麻烦,因为在arango 3中,图形函数被删除了。
在filterVertices UDF中有几种类似下面的情况

//check the page status
    if (mismatch == 1) {
        //stop traversal and not return mismatched
        return ['exclude', 'prune'];
    } else if (mismatch == 2) {
        //stop but return mismatched
        return 'prune';
    } else {
        //exclude mismatched but continue
        return 'exclude';
    }

我的问题是,在下面的aql中,过滤器的情况下,修剪和排除应该如何翻译?

FOR v, d, p IN 1..10 INBOUND "page/99999999999999" menu 
    LET filtered = CALL('udf::customFilter',v,p) 
    LET result = CALL('udf::customVisitor',v,d,p) 
RETURN {filtered:filtered,result:result}

如果我直接使用UDF,并将结果传递到LET参数中,然后手动排除(过滤)它们,性能会受到影响吗?

lymnna71

lymnna711#

更新:基于JavaScript的遍历不再可用。你可以使用AQL的遍历语言结构:https://docs.arangodb.com/3.11/aql/graphs/traversals/

一般来说,当你基于path对象(在你的例子中是p)编写过滤器时,你可以决定使用"prune", "exclude"。这里的例子是:

FILTER p.edges[1].type == 'FOO'
FILTER p.edges[*].label ALL == 'BAR'
FILTER p.vertices[*].age ALL >= 18

只要第二条边的类型不是FOO,第一条边就会进行修剪。第二个将在找到label != BAR等时进行修剪。优化器只能识别特定的深度检查或全局检查ALLNONEANY
如果在vertexedge输出上定义过滤器,您可以选择"exclude",在您的示例中为vd

FILTER d.type != "BAR"
FILTER v.name == "BAZ"

第一个将排除类型为“BAR”的所有边,第二个将仅包括名称为“BAZ”的顶点。在这两种情况下,遍历都将继续。
现在没有选择说PRUNE, INCLUDE
仅使用UDF实现过滤对性能非常不利。这是因为UDF是AQL的“黑盒”,尤其是不能优化到遍历中进行修剪。在我们的内部测试中,AQL遍历的性能仍然要好几个数量级,这就是我们决定采用这种方法的原因。
不幸的是,UDF函数比AQL only稍微灵活一些,所以可能有一些函数不能转换为FILTER only语句。然而,仍然有一个选项可以像3.0之前一样执行这些遍历,只需将整个遍历定义为用户定义的函数。这应该具有与之前相同的性能(高级算法是相同的,但是我们在Python 3.0中更改了许多其他内部部分,这些部分在这里具有性能副作用)。
新的UDF应该大致如下所示,并将startVertex作为输入:

var db = require("internal").db;
var traversal = require("@arangodb/graph/traversal");
var config = {
  datasource: traversal.collectionDatasource("menu"),
  filter: db._aqlfunctions.document("UDF::CUSTOMFILTER").code,
  visitor: db._aqlfunctions.document("UDF::CUSTOMVISITOR").code,
  maxDepth: 1 // has to be defined
};
var result = {
  visited: {
    vertices: [ ],
    paths: [ ]
  }
};
var traverser = new traversal.Traverser(config);
traverser.traverse(result, startVertex);
[...] // Do stuff with result here

如果您需要从UDF到FILTER的转换帮助,或者需要完整的遍历UDF启动和运行,请通过https://groups.google.com/forum/#直接联系我们!forum/arangodb.我们可能需要一些邮件来整理你需要的所有细节。

相关问题