mirror of https://gitee.com/bigwinds/arangodb
fun with custom visitors, cont.
This commit is contained in:
parent
b4ba07f765
commit
699b7e76f6
|
@ -144,6 +144,21 @@ instead.
|
|||
Note: The *connections* function parameter value will contain the edges connected to the
|
||||
vertex only if *order* was set to *preorder-expander*. Otherwise, the value of this parameter
|
||||
will be *undefined*.
|
||||
|
||||
The following custom visitor functions are predefined and can be used by specifying the function
|
||||
name in the *visitor* attribute:
|
||||
|
||||
- *"_AQL::PROJECTINGVISITOR"*: this visitor will produce an object with the attributes
|
||||
specified in *data.attributes* for each visited vertex. This can be used to create a
|
||||
projection of each visited vertex' document.
|
||||
|
||||
- *"_AQL::IDVISITOR"*: this visitor will return the _id attribute of each visited vertex.
|
||||
|
||||
- *"_AQL::KEYVISITOR"*: this visitor will return the _key attribute of each visited vertex.
|
||||
|
||||
- *"_AQL::COUNTINGVISITOR"*: this visitor will return a single number indicating the number
|
||||
of vertices visited.
|
||||
|
||||
|
||||
- *visitorReturnsResults*: only useful in combination with a custom AQL visitor function. If
|
||||
set to *true*, the data returned by the visitor will be appended to the result. If set to
|
||||
|
@ -151,6 +166,11 @@ instead.
|
|||
function can modify its *result* parameter value in-place. At the end of the traversal,
|
||||
*result* is expected to be an array.
|
||||
|
||||
- *data*: only useful in combination with a custom AQL visitor function. This attribute can
|
||||
be used to pass arbitrary data into the custom visitor function. The value contained in the
|
||||
*data* attribute will be made available to the *visitor* function in the *config.data*
|
||||
attribute.
|
||||
|
||||
By default, the result of the TRAVERSAL function is an array of traversed points. Each point
|
||||
is an object consisting of the following attributes:
|
||||
- *vertex*: The vertex at the traversal point
|
||||
|
|
|
@ -51,6 +51,46 @@ var RegexCache = { };
|
|||
|
||||
var UserFunctions = { };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prefab traversal visitors
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var DefaultVisitors = {
|
||||
"_AQL::PROJECTINGVISITOR" : {
|
||||
visitorReturnsResults: true,
|
||||
func: function (config, result, vertex) {
|
||||
var values = { };
|
||||
if (typeof config.data === "object" && Array.isArray(config.data.attributes)) {
|
||||
config.data.attributes.forEach(function (attribute) {
|
||||
values[attribute] = vertex[attribute];
|
||||
});
|
||||
}
|
||||
return values;
|
||||
}
|
||||
},
|
||||
"_AQL::IDVISITOR" : {
|
||||
visitorReturnsResults: true,
|
||||
func: function (config, result, vertex) {
|
||||
return vertex._id;
|
||||
}
|
||||
},
|
||||
"_AQL::KEYVISITOR" : {
|
||||
visitorReturnsResults: true,
|
||||
func: function (config, result, vertex) {
|
||||
return vertex._key;
|
||||
}
|
||||
},
|
||||
"_AQL::COUNTINGVISITOR" : {
|
||||
visitorReturnsResults: false,
|
||||
func: function (config, result) {
|
||||
if (result.length === 0) {
|
||||
result.push(0);
|
||||
}
|
||||
result[0]++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief type weight used for sorting and comparing
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -194,25 +234,34 @@ function reloadUserFunctions () {
|
|||
/// @brief get a user-function by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function GET_USERFUNCTION (name) {
|
||||
function GET_USERFUNCTION (name, config) {
|
||||
var prefix = DB_PREFIX(), reloaded = false;
|
||||
var key = name.toUpperCase();
|
||||
|
||||
if (! UserFunctions.hasOwnProperty(prefix)) {
|
||||
reloadUserFunctions();
|
||||
reloaded = true;
|
||||
}
|
||||
|
||||
if (! UserFunctions[prefix].hasOwnProperty(key) && ! reloaded) {
|
||||
// last chance
|
||||
reloadUserFunctions();
|
||||
}
|
||||
|
||||
if (! UserFunctions[prefix].hasOwnProperty(key)) {
|
||||
THROW(null, INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, name);
|
||||
}
|
||||
var func;
|
||||
|
||||
var func = UserFunctions[prefix][key].func;
|
||||
if (DefaultVisitors.hasOwnProperty(key)) {
|
||||
var visitor = DefaultVisitors[key];
|
||||
func = visitor.func;
|
||||
config.visitorReturnsResults = visitor.visitorReturnsResults;
|
||||
}
|
||||
else {
|
||||
if (! UserFunctions.hasOwnProperty(prefix)) {
|
||||
reloadUserFunctions();
|
||||
reloaded = true;
|
||||
}
|
||||
|
||||
if (! UserFunctions[prefix].hasOwnProperty(key) && ! reloaded) {
|
||||
// last chance
|
||||
reloadUserFunctions();
|
||||
}
|
||||
|
||||
if (! UserFunctions[prefix].hasOwnProperty(key)) {
|
||||
THROW(null, INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, name);
|
||||
}
|
||||
|
||||
func = UserFunctions[prefix][key].func;
|
||||
}
|
||||
|
||||
if (typeof func !== "function") {
|
||||
THROW(null, INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, name);
|
||||
|
@ -225,8 +274,8 @@ function GET_USERFUNCTION (name) {
|
|||
/// @brief create a user-defined visitor from a function name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function GET_VISITOR (name) {
|
||||
var func = GET_USERFUNCTION(name);
|
||||
function GET_VISITOR (name, config) {
|
||||
var func = GET_USERFUNCTION(name, config);
|
||||
|
||||
return function (config, result, vertex, path) {
|
||||
try {
|
||||
|
@ -250,8 +299,8 @@ function GET_VISITOR (name) {
|
|||
/// @brief create a user-defined filter from a function name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function GET_FILTER (name) {
|
||||
var func = GET_USERFUNCTION(name);
|
||||
function GET_FILTER (name, config) {
|
||||
var func = GET_USERFUNCTION(name, config);
|
||||
|
||||
return function (config, vertex, path) {
|
||||
try {
|
||||
|
@ -5059,7 +5108,8 @@ function TRAVERSAL_FUNC (func,
|
|||
endVertex : endVertex,
|
||||
weight : params.weight,
|
||||
defaultWeight : params.defaultWeight,
|
||||
prefill : params.prefill
|
||||
prefill : params.prefill,
|
||||
data: params.data
|
||||
};
|
||||
|
||||
if (typeof params.filter === "function") {
|
||||
|
@ -5456,7 +5506,7 @@ function SHORTEST_PATH_PARAMS (params) {
|
|||
|
||||
// add user-defined visitor, if specified
|
||||
if (typeof params.visitor === "string") {
|
||||
params.visitor = GET_VISITOR(params.visitor);
|
||||
params.visitor = GET_VISITOR(params.visitor, params);
|
||||
}
|
||||
else {
|
||||
params.visitor = TRAVERSAL_VISITOR;
|
||||
|
@ -5464,7 +5514,7 @@ function SHORTEST_PATH_PARAMS (params) {
|
|||
|
||||
// add user-defined filter, if specified
|
||||
if (typeof params.filter === "string") {
|
||||
params.filter = GET_FILTER(params.filter);
|
||||
params.filter = GET_FILTER(params.filter, params);
|
||||
}
|
||||
|
||||
if (typeof params.distance === "string") {
|
||||
|
@ -5686,7 +5736,7 @@ function TRAVERSAL_PARAMS (params) {
|
|||
|
||||
// add user-defined visitor, if specified
|
||||
if (typeof params.visitor === "string") {
|
||||
params.visitor = GET_VISITOR(params.visitor);
|
||||
params.visitor = GET_VISITOR(params.visitor, params);
|
||||
}
|
||||
else {
|
||||
params.visitor = TRAVERSAL_VISITOR;
|
||||
|
@ -5694,7 +5744,7 @@ function TRAVERSAL_PARAMS (params) {
|
|||
|
||||
// add user-defined filter, if specified
|
||||
if (typeof params.filter === "string") {
|
||||
params.filter = GET_FILTER(params.filter);
|
||||
params.filter = GET_FILTER(params.filter, params);
|
||||
}
|
||||
|
||||
return params;
|
||||
|
@ -6045,7 +6095,7 @@ function TRAVERSAL_TREE_PARAMS (params, connectName, func) {
|
|||
|
||||
// add user-defined visitor, if specified
|
||||
if (typeof params.visitor === "string") {
|
||||
params.visitor = GET_VISITOR(params.visitor);
|
||||
params.visitor = GET_VISITOR(params.visitor, params);
|
||||
}
|
||||
else {
|
||||
params.visitor = TRAVERSAL_TREE_VISITOR;
|
||||
|
@ -6053,7 +6103,7 @@ function TRAVERSAL_TREE_PARAMS (params, connectName, func) {
|
|||
|
||||
// add user-defined filter, if specified
|
||||
if (typeof params.filter === "string") {
|
||||
params.filter = GET_FILTER(params.filter);
|
||||
params.filter = GET_FILTER(params.filter, params);
|
||||
}
|
||||
|
||||
params.connect = AQL_TO_STRING(connectName);
|
||||
|
|
Loading…
Reference in New Issue