Call

Cypher®.Call generates Cypher CALL subqueries. To do this, instantiate Cypher.Call with a valid subquery as a parameter in the constructor.

new Cypher.Call(subquery);

In the following example, Cypher.Call receives a Cypher.Match clause. This generates a MATCH clause wrapped by a CALL.

const dog = new Cypher.Node({ labels: ["Dog"] });
const person = new Cypher.Node({ labels: ["Person"] });
const dogName = new Cypher.NamedVariable("dogName");

const pattern = new Cypher.Pattern(person).related(new Cypher.Relationship({ type: "HAS_DOG" })).to(dog);
const subquery = new Cypher.Match(pattern).return([dog.property("name"), dogName]);

const callClause = new Cypher.Call(subquery).return(dogName);
const { cypher, params } = callClause.build();
CALL {
    MATCH (this0:Person)-[this1:HAS_DOG]->(this2:Dog)
    RETURN this2.name AS dogName
}
RETURN dogName

Variable scope

Variables can be added to the scope of the CALL subquery by passing them as an array to the second argument of the constructor. These variables will then be available for use in the subquery.

new Cypher.Call(subquery, [var1, var2]);

The following code includes two variables in the CREATE statement inside the CALL. The generated Cypher adds movieNode (this0) and actorNode (this1) in the subquery scope:

const movieNode = new Cypher.Node();
const actorNode = new Cypher.Node();

const createSubquery = new Cypher.Create(new Cypher.Pattern(movieNode).related().to(actorNode));

const clause = new Cypher.Call(createSubquery, [
    movieNode,
    actorNode,
]);
CALL (this0, this1) {
    CREATE (this0)-[this2]->(this1)
}

To import all variables from the outer scope, set the second parameter to the string "*":

const movieNode = new Cypher.Node();
const actorNode = new Cypher.Node();

const createSubquery = new Cypher.Create(new Cypher.Pattern(movieNode).related().to(actorNode));

const clause = new Cypher.Call(createSubquery, "*");
CALL (*) {
    CREATE (this0)-[this2]->(this1)
}

.inTransactions

The .inTransactions method appends the IN TRANSACTIONS modifier to a CALL subquery, causing it to execute in separate transactions:

new Call(subquery).inTransactions();
CALL {
    // Subquery
} IN TRANSACTIONS

The inTransactions method supports optional settings for customizing transactional behavior, including error handling, rows per transaction, and concurrency. Settings are passed as an object:

new Call(subquery).inTransactions({
    ofRows: 10
});

Supported settings:

Setting Description Cypher

ofRows

Number of rows per transaction

IN TRANSACTIONS OF [n] ROWS

onError

Error handling: continue, break, or fail

ON ERROR [CONTINUE | BREAK | FAIL]

concurrentTransactions

Maximum number of concurrent transactions

IN [n] CONCURRENT TRANSACTIONS

retry

Retries failed transactions. Can be true or a number (duration in seconds)

ON ERROR RETRY [FOR x SECONDS]

Example 1: Concurrent transactions of rows

const clause = new Cypher.Call(subquery).inTransactions({
    ofRows: 10,
    concurrentTransactions: 5
});
CALL {
    // subquery
} IN 5 CONCURRENT TRANSACTIONS OF 10 ROWS

Example 2: Retry with maximum duration

const clause = new Cypher.Call(subquery).inTransactions({
    retry: 10
});
CALL {
    // subquery
} TRANSACTIONS ON ERROR RETRY FOR 10 SECONDS

Example 3: Retry with fallback strategy

const clause = new Cypher.Call(subquery).inTransactions({
    retry: true,
    onError: "continue"
});
CALL {
    // subquery
} TRANSACTIONS ON ERROR RETRY THEN CONTINUE

Optional Call

The .optional() method transforms a CALL subquery into an OPTIONAL CALL subquery.

new Cypher.Call(subquery).optional();

Alternatively, you can use the OptionalCall clause to directly create an OPTIONAL CALL:

new Cypher.OptionalCall(deleteSubquery);

Both will generate the same Cypher:

OPTIONAL CALL {
    // Subquery
}