Custom, Cypher Based Procedures and Functions

I wanted for a long time to be able to register Cypher statements as proper procedures and functions, so that they become callable in a standalone way.

You can achieve that with the apoc.custom.declareProcedure and apoc.custom.dclareFunction procedure calls. Those register a given Cypher statement, prefixed with the custom.* namespace, overriding potentially existing ones, so you can redefine them as needed.

Here is a simple example:

CALL apoc.custom.declareProcedure('answer() :: INT','RETURN 42 as answer')

This registers the statement as procedure custom.answer that you then can call. As no information on parameter and return types is given, it just returns a stream of columns of maps called row.

CALL custom.answer() YIELD row
RETURN row.answer()

The same is possible as a function:

CALL apoc.custom.declareFunction('answer() :: (result::INT)','RETURN 42')
If you override procedures or functions you might need to call call dbms.clearQueryCaches() as lookups to internal ids are kept in compiled query plans.

Custom Procedures with apoc.custom.declareProcedure

The given statement will be registered as a procedure, the results will be turned into a stream of records.

Input parameters

Name Type Default

signature

STRING?

null

statement

STRING?

null

mode

STRING?

read

description

STRING?

The type names are what you would expect and see in outputs of SHOW PROCEDURES or apoc.help just without the ?. The default values are parsed as JSON.

Type Names
  • FLOAT, DOUBLE, INT, INTEGER, NUMBER, LONG

  • TEXT, STRING

  • BOOL, BOOLEAN

  • POINT, GEO, GEOMETRY

  • DATE, DATETIME, LOCALDATETIME, TIME, LOCALTIME, DURATION

  • NODE, REL, RELATIONSHIP, EDGE, PATH

  • MAP

  • LIST TYPE, LIST OF TYPE (where TYPE can be one of the previous values)

  • ANY

Find neighbours of a node by name
CALL apoc.custom.declareProcedure('neighbours(name::STRING) :: NODE',
  'MATCH (n:Person {name:$name})-->(nb) RETURN nb as neighbour','read',
  'get neighbours of a person');

CALL custom.neighbours('Keanu Reeves') YIELD neighbour;

Custom Functions with apoc.custom.declareFunction

Given statement will be registered as a statement, the results into a single value. If the given output type is a list, results will be collected into a list, otherwise the first row will be used. The statement needs to return a single column, otherwise an error is thrown.

Input parameters

Name Type Default

signature

STRING?

null

statement

STRING?

null

forceSingle

BOOLEAN?

false

description

STRING?

The type names are what you would expect and see in outputs of SHOW PROCEDURES or apoc.help just without the ?. The default values are parsed as JSON.

List of registered procedures/function with apoc.custom.list

The procedure apoc.custom.list provide a list of all registered procedures/function via apoc.custom.declareProcedure and apoc.custom.declareFunction

Given the this call:

CALL apoc.custom.list

The the output will look like the following table:

type name description mode statement inputs outputs forceSingle

"function"

"answer"

<null>

<null>

"RETURN $input as answer"

[["input","number"]]

"long"

false

"procedure"

"answer"

"Procedure that answer to the Ultimate Question of Life, the Universe, and Everything"

"read"

"RETURN $input as answer"

[["input","int","42"]]

[["answer","number"]]

<null>

Remove a procedure apoc.custom.removeProcedure

The procedure apoc.custom.removeProcedure allows to delete the targeted custom procedure.

Given the this call:

CALL apoc.custom.removeProcedure(<name>)

Fields:

argument description

name

the procedure name

Remove a procedure apoc.custom.removeFunction

The procedure apoc.custom.removeFunction allows to delete the targeted custom function.

Given the this call:

CALL apoc.custom.removeFunction(<name>)

Fields:

argument description

name

the function name

How to manage procedure/function replication in a Causal Cluster

In order to replicate the procedure/function in a cluster environment you can tune the following parameters:

name type description

apoc.custom.procedures.refresh

long (default 60000)

the refresh time that allows replicating the procedure/function changes to each cluster member

Export metadata

To import custom procedures in another database (for example after a ./neo4j-admin backup and /neo4j-admin restore), please see the apoc.systemdb.export.metadata procedure.