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)
}

.importWith

This method is deprecated in favor of Variable scope.

importWith cannot be used if scope variables are defined and will throw an error.

To add variables to a CALL subquery context, you need to add a WITH statement. This can be achieved by using the .importWith method.

const dog = new Cypher.Node();
const person = new Cypher.Node();

const dogName = new Cypher.NamedVariable("dogName");

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

const clause = new Cypher.Match(new Cypher.Pattern(person, { labels: ["Person"] }))
    .call(subquery)
    .importWith(person)
    .return(dogName);
MATCH (this0:Person)
CALL {
    WITH this0
    MATCH (this0:Person)-[this1:HAS_DOG]->(this2:Dog)
    RETURN this2.name AS dogName
}
RETURN dogName

Note how this example uses .concat to combine the initial MATCH and CALL clauses.

.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
}