簡體   English   中英

將filterVertice UDF從ArangoDB 2.8遷移到ArangoDB 3

[英]Migrating a filterVertice UDF from ArangoDB 2.8 to ArangoDB 3

我當前正在將TRAVERSAL函數從arangoDB 2遷移到arangoDB3。aql有一個自定義葉子訪問者和一個帶有自定義AQL函數的filterVertices選項(用於更具體的過濾)。

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

葉子訪問者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中的FILTER情況下,應如何准確修剪修剪和排除?

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參數並手動排除(過濾),會不會影響性能?

一般來說"prune", "exclude"當您基於path對象(在您的情況下為p )編寫過濾器時"prune", "exclude"可以決定"prune", "exclude"在這里,優化器將識別出任何更長的路徑都無法滿足特定條件。 示例如下:

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

每當第二條邊的類型不為FOO時,第一條將進行修剪。 只要找到label != BAR等,第二個就會修剪。優化器只能識別特定的深度檢查或全局檢查ALLNONEANY

如果是在vd的情況下,是在vertexedge輸出上定義過濾器,則可以決定"exclude"

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

第一個將排除所有類型為“ BAR”的邊,第二個將僅包括名稱為“ BAZ”的頂點。 在這兩種情況下,遍歷都會繼續。

目前沒有選擇說PRUNE, INCLUDE

僅使用UDF實施過濾對性能非常不利。 這是因為UDF是AQL的“黑匣子”,特別是無法將其優化為遍歷以進行修剪。 在我們的內部測試中,AQL遍歷的性能仍然要好幾個數量級,這就是我們決定采用這種方式的原因。

不幸的是,UDF函數比僅AQL稍微靈活一些,因此可能有些函數無法轉換為FILTER only語句。 但是,仍然可以通過將整個遍歷定義為用戶定義的函數來以與3.0之前相同的方式執行這些遍歷。 它應該具有與以前相同的性能(高級算法是相同的,但是我們在3.0中更改了許多其他內部部件,這些部件在這里具有性能副作用)。

這在這里有更詳細的解釋: https : //docs.arangodb.com/3.1/Manual/Graphs/Traversals/UsingTraversalObjects.html

您的新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直接與我們聯系。 我們可能需要一些郵件來整理您需要的所有詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM