ArangoDB Manual Pages


Extending AQL with User Functions

Conventions

AQL comes with a built-in set of functions, but it is no full-feature programming language.

To add missing functionality or to simplifiy queries, users may add own functions to AQL. These functions can be written in Javascript, and must be registered via an API.

In order to avoid conflicts with existing or future built-in function names, all user functions must be put into separate namespaces. Invoking a user functions is then possible by referring to the fully-qualified function name, which includes the namespace, too.

The : symbol is used inside AQL as the namespace separator. Using the namespace separator, users can create a multi-level hierarchy of function groups if required.

Examples:

RETURN myfunctions::myfunc()

RETURN myfunctions::math::random()

Note: as all function names in AQL, user function names are also case-insensitive.

Built-in AQL functions reside in the namespace _aql, which is also the default namespace to look in if an unqualified function name is found. Adding user functions to the _aql namespace is disallowed and will fail.

User functions can take any number of input arguments and should provide one result. They should be kept purely functional and thus free of side effects and state.

Especially it is unsupported to modify any global variables, or to change data of a collection from an AQL user function.

User function code is late-bound, and may thus not rely on any variables that existed at the time of declaration. If user function code requires access to any external data, it must take care to set up the data by itself.

User functions must only return primitive types (i.e. null, boolean values, numeric values, string values) or aggregate types (lists or documents) composed of these types. Returning any other Javascript object type from a user function may lead to undefined behavior and should be avoided.

Registering and Unregistering User Functions

AQL user functions can be registered using the aqlfunctions object as follows:

var aqlfunctions = require("org/arangodb/aql/functions");

To register a function, the fully qualified function name plus the function code must be specified.

aqlfunctions.register(name, code, isDeterministic)

Registers an AQL user function, identified by a fully qualified function name. The function code in code must be specified as a Javascript function or a string representation of a Javascript function.

If a function identified by name already exists, the previous function definition will be updated.

The isDeterministic attribute can be used to specify whether the function results are fully deterministic (i.e. depend solely on the input and are the same for repeated calls with the same input values). It is not used at the moment but may be used for optimisations later.

Examples

arangosh> require("org/arangodb/aql/functions").register("myfunctions::temperature::celsiustofahrenheit",
function (celsius) {
return celsius * 1.8 + 32;
});

It is possible to unregister a single user function, or a whole group of user functions (identified by their namespace) in one go:

aqlfunctions.unregister(name)

Unregisters an existing AQL user function, identified by the fully qualified function name.

Trying to unregister a function that does not exist will result in an exception.

Examples

arangosh> require("org/arangodb/aql/functions").unregister("myfunctions::temperature::celsiustofahrenheit");
aqlfunctions.unregisterGroup(prefix)

Unregisters a group of AQL user function, identified by a common function group prefix.

This will return the number of functions unregistered.

Examples

arangosh> require("org/arangodb/aql/functions").unregisterGroup("myfunctions::temperature");
arangosh> require("org/arangodb/aql/functions").unregisterGroup("myfunctions");

To get an overview of which functions are currently registered, the toArray function can be used:

aqlfunctions.toArray()

Returns all previously registered AQL user functions, with their fully qualified names and function code.

The result may optionally be restricted to a specified group of functions by specifying a group prefix:

aqlfunctions.toArray(prefix)

Examples

To list all available user functions:

arangosh> require("org/arangodb/aql/functions").toArray();

To list all available user functions in the myfunctions namespace:

arangosh> require("org/arangodb/aql/functions").toArray("myfunctions");

To list all available user functions in the myfunctions::temperature namespace:

arangosh> require("org/arangodb/aql/functions").toArray("myfunctions::temperature");