CALL[…​YIELD]

Introduction

Procedures are called using the CALL clause.

Each procedure call needs to specify all required procedure arguments. This may be done either explicitly, by using a comma-separated list wrapped in parentheses after the procedure name, or implicitly by using available query parameters as procedure call arguments. The latter form is available only in a so-called standalone procedure call, when the whole query consists of a single CALL clause.

Most procedures return a stream of records with a fixed set of result fields, similar to how running a Cypher® query returns a stream of records. The YIELD sub-clause is used to explicitly select which of the available result fields are returned as newly-bound variables from the procedure call to the user or for further processing by the remaining query. Thus, in order to be able to use YIELD, the names (and types) of the output parameters need be known in advance. Each yielded result field may optionally be renamed using aliasing (i.e. resultFieldName AS newName). All new variables bound by a procedure call are added to the set of variables already bound in the current scope. It is an error if a procedure call tries to rebind a previously bound variable (i.e. a procedure call cannot shadow a variable that was previously bound in the current scope).

This section explains how to determine a procedure’s input parameters (needed for CALL) and output parameters (needed for YIELD).

Inside a larger query, the records returned from a procedure call with an explicit YIELD may be further filtered using a WHERE sub-clause followed by a predicate (similar to WITH …​ WHERE …​).

If the called procedure declares at least one result field, YIELD may generally not be omitted. However YIELD may always be omitted in a standalone procedure call. In this case, all result fields are yielded as newly-bound variables from the procedure call to the user.

Neo4j supports the notion of VOID procedures. A VOID procedure is a procedure that does not declare any result fields and returns no result records and that has explicitly been declared as VOID. Calling a VOID procedure may only have a side effect and thus does neither allow nor require the use of YIELD. Calling a VOID procedure in the middle of a larger query will simply pass on each input record (i.e. it acts like WITH * in terms of the record stream).

Neo4j comes with a number of built-in procedures. For a list of these, see Operations Manual → Built-in procedures.

Users can also develop custom procedures and deploy to the database. See User-defined procedures for details.

The following examples show how to pass arguments to and yield result fields from a procedure call. All examples use the following procedure:

public class IndexingProcedure
{
    @Context
    public GraphDatabaseService db;

    /**
     * Adds a node to a named explicit index. Useful to, for instance, update
     * a full-text index through cypher.
     * @param indexName the name of the index in question
     * @param nodeId id of the node to add to the index
     * @param propKey property to index (value is read from the node)
     */
    @Procedure(mode = Mode.WRITE)
    public void addNodeToIndex( @Name("indexName") String indexName,
                                @Name("node") long nodeId,
                                @Name( value = "propKey", defaultValue = "name" ) String propKey )
    {
        Node node = db.getNodeById( nodeId );
        db.index()
          .forNodes( indexName )
          .add( node, propKey, node.getProperty( propKey ) );
    }
}

Call a procedure using CALL

This calls the built-in procedure db.labels, which lists all labels used in the database.

Query
CALL `db`.`labels`
Table 1. Result
label

"User"

"Administrator"

2 rows

View the signature for a procedure

To CALL a procedure, its input parameters need to be known, and to use YIELD, its output parameters need to be known. The built-in procedure dbms.procedures returns the name, signature and description for all procedures. The following query can be used to return the signature for a particular procedure:

Query
CALL dbms.procedures() YIELD name, signature
WHERE name='dbms.listConfig'
RETURN signature

We can see that the dbms.listConfig has one input parameter, searchString, and three output parameters, name, description and value.

Table 2. Result
signature

"dbms.listConfig(searchString = :: STRING?) :: (name :: STRING?, description :: STRING?, value :: STRING?, dynamic :: BOOLEAN?)"

1 row

Call a procedure using a quoted namespace and name

This calls the built-in procedure db.labels, which lists all labels used in the database.

Query
CALL `db`.`labels`

Call a procedure with literal arguments

This calls the example procedure org.neo4j.procedure.example.addNodeToIndex using literal arguments. The arguments are written out directly in the statement text.

Query
CALL org.neo4j.procedure.example.addNodeToIndex('users', 0, 'name')

Since our example procedure does not return any result, the result is empty.

Call a procedure with parameter arguments

This calls the example procedure org.neo4j.procedure.example.addNodeToIndex using parameters as arguments. Each procedure argument is taken to be the value of a corresponding statement parameter with the same name (or null if no such parameter has been given).

Parameters
{
  "indexName" : "users",
  "node" : 0,
  "propKey" : "name"
}
Query
CALL org.neo4j.procedure.example.addNodeToIndex

Since our example procedure does not return any result, the result is empty.

Call a procedure with mixed literal and parameter arguments

This calls the example procedure org.neo4j.procedure.example.addNodeToIndex using both literal and parameter arguments.

Parameters
{
  "node" : 0
}
Query
CALL org.neo4j.procedure.example.addNodeToIndex('users', $node, 'name')

Since our example procedure does not return any result, the result is empty.

Call a procedure with literal and default arguments

This calls the example procedure org.neo4j.procedure.example.addNodeToIndex using literal arguments. That is, arguments that are written out directly in the statement text, and a trailing default argument that is provided by the procedure itself.

Query
CALL org.neo4j.procedure.example.addNodeToIndex('users', 0)

Since our example procedure does not return any result, the result is empty.

Call a procedure within a complex query using CALL YIELD

This calls the built-in procedure db.labels to count all labels used in the database.

Query
CALL db.labels() YIELD label
RETURN count(label) AS numLabels

Since the procedure call is part of a larger query, all outputs must be named explicitly.

Call a procedure and filter its results

This calls the built-in procedure db.labels to count all in-use labels in the database that contain the word 'User'.

Query
CALL db.labels() YIELD label
WHERE label CONTAINS 'User'
RETURN count(label) AS numLabels

Since the procedure call is part of a larger query, all outputs must be named explicitly.

Call a procedure within a complex query and rename its outputs

This calls the built-in procedure db.propertyKeys as part of counting the number of nodes per property key that is currently used in the database.

Query
CALL db.propertyKeys() YIELD propertyKey AS prop
MATCH (n)
WHERE n[prop] IS NOT NULL RETURN prop, count(n) AS numNodes

Since the procedure call is part of a larger query, all outputs must be named explicitly.