Overview
CALL Subqueries
CALL { ... } isolates a scope and lets you compose post-aggregation logic + batch writes.
Why it matters
Subqueries are how you write 'do this once per row' without leaving Cypher — and IN TRANSACTIONS OF N ROWS is how you safely write millions of rows in one statement.
Going deeper
CALL { ... } runs a subquery with its own scope, executed once per incoming row (when it imports variables):
MATCH (c:Customer)
CALL {
WITH c
MATCH (c)-[:PLACED]->(o:Order)
RETURN sum(o.total) AS spend
}
RETURN c.name, spend ORDER BY spend DESC;
The killer feature for writes is batching:
CALL {
MATCH (o:Order) WHERE o.archived IS NULL
SET o.archived = false
} IN TRANSACTIONS OF 1000 ROWS;
This commits every 1000 rows, so a multi-million-row update doesn't build one giant transaction that exhausts the heap. Trade-off: atomicity is now per-batch, not whole-statement — if it fails at row 2.5M, the first 2.5M are already committed, so make the operation idempotent (re-runnable).
