APOC and the extension ecosystem
|
This section documents the current Neo4j This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, as Neo4j iterates quickly. This section’s bibliography lists the reference material consulted while preparing these pages. |
APOC ("Awesome Procedures On Cypher") is the standard extension library for Neo4j — hundreds of procedures and functions covering refactoring, data import/export, graph algorithms, and utilities that plain Cypher does not expose. This page covers installing and locking it down, its most commonly used procedure families, and a brief pointer to the wider extension ecosystem beyond APOC itself.
Installing and allowlisting APOC
APOC ships as a separate .jar dropped into the server’s plugins directory (or pulled in automatically on
Aura, where a curated subset is pre-installed). Because many APOC procedures can read/write the filesystem,
call out to JDBC, or run arbitrary Cypher, a server does not expose them all by default: two settings in
neo4j.conf control what is actually callable.
# neo4j.conf
# https://neo4j.com/docs/apoc/current/installation/
# Required for apoc.load.json / apoc.export.*.* to read and write files on disk
# instead of only remote URLs.
apoc.import.file.enabled=true
apoc.export.file.enabled=true
# Procedure/function allowlist: only names matching one of these globs are
# callable at all. Narrow this to the families a deployment actually needs
# rather than allowlisting the whole library.
dbms.security.procedures.allowlist=apoc.coll.*,apoc.load.*,apoc.refactor.*,apoc.periodic.*,apoc.export.*,apoc.path.*
# Procedures matching this pattern additionally run without Cypher's normal
# read/write permission checks -- keep this list at least as narrow as the
# allowlist above.
dbms.security.procedures.unrestricted=apoc.load.*,apoc.periodic.*
The server must be restarted after editing neo4j.conf. See
APOC Installation for the plugin drop-in steps per
deployment type and the full list of security settings, and
APOC Introduction for how the library is organized into
procedure/function families. The library itself is catalogued at
the APOC documentation; its project home and release notes live at
APOC on Neo4j Labs.
Refactoring procedures
apoc.refactor.* reshapes an already-loaded graph: merging duplicate nodes, and renaming labels,
relationship types, or properties without a full reload.
// Two Person nodes for the same person (e.g. found via a dedup query);
// merge them into one, combining scalar properties into arrays where they differ.
MATCH (p1:Person {email: "ada@x.io"}), (p2:Person {email: "ada@x.io"})
WHERE id(p1) <> id(p2)
CALL apoc.refactor.mergeNodes([p1, p2], {properties: "combine", mergeRels: true})
YIELD node
RETURN node;
// Rename a label across the whole graph.
CALL apoc.refactor.rename.label("Person", "Customer") YIELD total RETURN total;
// Rename a relationship type.
CALL apoc.refactor.rename.type("ACTED_IN", "PERFORMED_IN") YIELD total RETURN total;
Loading JSON and JDBC data
apoc.load.json streams a JSON document or NDJSON feed (local file or URL) as one row per top-level value;
apoc.load.jdbc runs a SQL query against any JDBC-reachable database and streams back one row per result
row, both driving a downstream MERGE to build the graph.
// Load a JSON array of people and upsert them as nodes.
CALL apoc.load.json("https://example.com/data/people.json")
YIELD value
MERGE (p:Person {id: value.id})
SET p.name = value.name, p.email = value.email;
// Pull rows from a relational source via JDBC (driver jar must also be on the
// server's plugins/classpath) and upsert them.
CALL apoc.load.jdbc(
"jdbc:postgresql://localhost:5432/mydb?user=neo4j&password=change-me",
"SELECT id, name, email FROM customers"
)
YIELD row
MERGE (c:Customer {id: row.id})
SET c.name = row.name, c.email = row.email;
Path utility functions
The apoc.path.* family expands or filters paths with more control than a plain Cypher pattern — bounding
by relationship type/direction, label, or level without hand-writing a variable-length pattern for every
case.
// All nodes reachable within 2 hops via ACTED_IN in either direction.
MATCH (start:Person {name: "Keanu Reeves"})
CALL apoc.path.subgraphNodes(start, {
relationshipFilter: "ACTED_IN>|<ACTED_IN",
maxLevel: 2
})
YIELD node
RETURN node;
Periodic and batch processing
apoc.periodic.iterate splits a large update into batches, committing each one in its own transaction
(optionally in parallel) so a bulk write on millions of rows does not hold one giant transaction open or
blow the heap.
// Recompute a derived score for every unprocessed Person, 10k nodes per
// transaction, four batches running in parallel.
CALL apoc.periodic.iterate(
"MATCH (p:Person) WHERE p.processed IS NULL RETURN p",
"SET p.processed = true, p.score = size((p)-[:ACTED_IN]->())",
{batchSize: 10000, parallel: true, concurrency: 4}
)
YIELD batches, total, timeTaken, errorMessages
RETURN batches, total, timeTaken, errorMessages;
Exporting data
apoc.export.csv. and apoc.export.json. write the result of a query, a set of nodes/relationships, or
the whole database to a file (subject to apoc.export.file.enabled above) or return it inline as a stream.
// Export a query's results to CSV on the server's import directory.
CALL apoc.export.csv.query(
"MATCH (p:Person)-[:ACTED_IN]->(m:Movie) RETURN p.name AS actor, m.title AS movie",
"actors.csv",
{}
);
// Export the entire database as JSON, one line per node/relationship.
CALL apoc.export.json.all("full-export.json", {});
The wider extension ecosystem
APOC is the general-purpose toolbox; a few other officially maintained projects extend Neo4j in more specific directions and are worth knowing about even though they are out of scope for this page:
-
The Neo4j GraphQL Library generates a GraphQL API (queries, mutations, and subscriptions) directly from a GraphQL type-definitions schema, translating each request into Cypher — Neo4j GraphQL Library.
-
The Kafka Connector streams data between Neo4j and Apache Kafka topics in both directions (source and sink), for event-driven pipelines that keep the graph in sync with the rest of a system — Neo4j Streams / Kafka Connector.
-
The Spark Connector reads and writes Neo4j nodes and relationships as Spark DataFrames, for bulk ETL and analytics jobs run from a Spark cluster — Neo4j Connector for Apache Spark.
Related pages
-
Getting started with Neo4j — editions, deployment, and the two shells these examples were run from.
-
Advanced Cypher querying — the Cypher patterns (
MERGE, subqueries, aggregation) that the loading and refactoring examples above build on.