abs- computes the absolute value of a numberpow- computes v^xtrim- removes leading and trailing spaces.
UpperCaseOdd) is not always trivial. The function needs to be usable to a wide audience for it to be considered. In the past, FalkorDB has rejected requests for adding new functions when these were too specific and did not add significant value for most users.
However, with the support of UDFs, everyone can extend FalkorDB’s functionality with their own set of functions. The following sections introduce UDFs and explain how to manage and use them within FalkorDB.
Practical Example
To introduce UDFs, review the following complete example, which loads a new UDF library called “StringUtils” that includes a single function called “UpperCaseOdd”. Once loaded, the script puts the function to use.Commands Specification
The FalkorDB-PY Python client provides convenient access to UDF functionality, but FalkorDB also exposes this functionality via a set of GRAPH.UDF <sub_cmd> commands.GRAPH.UDF LOAD [REPLACE] <Lib> <script>
To add a UDF, callGRAPH.UDF LOAD followed by an optional REPLACE keyword. When specified, the REPLACE keyword replaces an already registered UDF library. The command then takes two arguments: the library name and the library script (written in JavaScript).
A UDF library can expose multiple UDFs. The following example shows a script that includes both non-exposed utility functions and a number of callable functions:
falkor.register and provide the name you wish to expose your function under, followed by either an anonymous function or the actual function.
For example:
GRAPH.UDF LIST [Lib] [WITHCODE]
To list loaded UDF libraries you can either use the FalkorDB-PYudf_list function or invoke the GRAPH.UDF LIST command via a direct connection to the DB.
The command takes two optional arguments:
- Lib: list only a specific library.
- WITHCODE: to include the library source code as part of the output.
GRAPH.UDF LIST WITHCODE will generate the following output:
GRAPH.UDF DELETE <library>
To remove a UDF library use either theudf_delete FalkorDB-PY function, or send a GRAPH.UDF DELETE <library> command via a direct connection to the database.
For example:
GRAPH.UDF FLUSH
Similar to deleteGRAPH.UDF FLUSH removes all UDF libraries from the database.
Datatypes
Any datatype available in FalkorDB is accessible within UDFs, these include: Scalar, Node, Edge & Path objects.Node
In a UDF, a node object exposes itsID, labels and attributes via the corresponding properties:
id- node internal IDlabels- node’s labelsattributes- node’s attributes
getNeighbors function. The getNeighbors function accepts an optional config map:
Edge
In a UDF, an edge object exposes itsID, type, source, target and attributes via the corresponding properties:
id- edge internal IDtype- edge’s relationship typesource- edge’s start nodetarget- edge’s end nodeattributes- edge’s attributes
Path
In a UDF, a path object exposes itsnodes, length and relationships via the corresponding properties:
nodes- path’s nodeslength- path’s lengthrelationships- path’s edges
Global objects
Breaking change (v4.16): Thefalkor.traverse()function has been removed. If your UDF scripts callfalkor.traverse(...), migrate them to usegraph.traverse(...)instead — the API accepts the same arguments. Thegraphobject is the new unified interface for all graph-level operations.
Graph
UDFs have access to a globalgraph object which represents the current graph executing the UDF.
The object exposes the following functions:
graph.traverse
Similar to the node’sgetNeighbors function (see docs above), graph.traverse can perform multi-source traversal, which can be faster than performing multiple individual calls to getNeighbors.
graph.getNodeById
Description
Looks up and returns a single node by its internal graph ID. Returnsnull if no node with the given ID exists.
Syntax
Parameters
Return value
A Node object if the node exists, otherwisenull.
Example
graph.iterateNodes
Description
Returns an iterator over all nodes in the graph that carry the specified label. The iterator is consumed with a standardfor...of loop and yields Node objects one at a time.
If no nodes with the given label exist, the iterator is empty and the loop body never executes.
Syntax
Parameters
Return value
An iterator of Node objects matching the given label.Example
graph.iterateEdges
Description
Returns an iterator over all edges in the graph that have the specified relationship type. The iterator is consumed with a standardfor...of loop and yields Edge objects one at a time.
If no edges with the given relationship type exist, the iterator is empty and the loop body never executes.
Syntax
Parameters
Return value
An iterator of Edge objects matching the given relationship type.Example
Falkor
Thefalkor global object represents the FalkorDB database and is used mostly to register UDFs. The object exposes two functions:
log- logs a message to the database stdout.register- exposes a function to the database.
falkor.log
Description
Logs a message to the database stdoutSyntax
Parameters
falkor.register
Description
Register a function to the databaseSyntax
Parameters
Example
Advanced examples
In this example, we’ll implement Jaccard similarity for nodes. Jaccard’s formula is: J(A,B) = |A ∩ B| / |A ∪ B| = |A ∩ B| / (|A| + |B| - |A ∩ B|) In simple terms, to compute Jaccard similarity for two nodes A and B, compute the number of shared neighbors between them and divide it by the total number of neighbors. If A and B have the same neighbors, their similarity value is 1. If they have no shared neighbors, their similarity value is 0. To start, define two UDFs (union and intersection) in a collection.js file:similarity.js as follows:
union and intersection from collection.js, and also collects A’s and B’s neighbors via a call to getNeighbors.
The remaining step is to load these UDF libraries into FalkorDB and use them:
collection and similarity, construct a graph, and compute Jaccard similarity between Alice and every other node in the graph via the query:
Custom Traversals
In some situations where you want fine control over the way graph traversals are made, Cypher might not be flexible enough. Consider the following requirement: collect all reachable nodes from a given start node, where a neighbor node is added to the expanded path if its amount value is greater than the accumulated sum of amounts on the current path. The following UDF accomplishes this traversal. It performs a DFS and only expands to neighbors whoseamount value is greater than the accumulated sum of amounts along the current path:
FLEX
FLEX (FalkorDB Library of Extensions) is FalkorDB’s open source community UDF package, available at github.com/FalkorDB/flex. It contains a variety of useful functionality, including:- String and set similarity metrics for fuzzy matching and comparison
- Date and time manipulation, formatting, and parsing
- Low-level bitwise operations on integers
Limitations
Currently, UDFs are not allowed to modify the graph in any way. You cannot update graph entities within a UDF, nor can you add or delete entities.
Frequently Asked Questions
What are UDFs in FalkorDB?
What are UDFs in FalkorDB?
UDFs (User Defined Functions) are custom extensions written in JavaScript that let you add new functions to FalkorDB without modifying its source code. They are loaded via the
udf_load command and called in Cypher queries.Can UDFs modify the graph?
Can UDFs modify the graph?
No. Currently, UDFs are read-only — they cannot update, add, or delete graph entities. They can only compute and return values.
How do I call a UDF in a Cypher query?
How do I call a UDF in a Cypher query?
UDFs are called using the format
LibraryName.FunctionName(args). For example: RETURN StringUtils.UpperCaseOdd('hello'). The library name is specified when loading the UDF.What language are UDFs written in?
What language are UDFs written in?
UDFs are written in JavaScript. You define a function and register it using
falkor.register('FunctionName', fn) to expose it to FalkorDB.