Running Cypher fragments

We can use Cypher as a safe, graph-aware, partially compiled scripting language within APOC.

Procedure Overview

The supported procedures are described in the table below:

Qualified Name Type Release

apoc.cypher.doIt

- executes writing fragment with the given parameters

Procedure

APOC Core

apoc.cypher.run

- executes reading fragment with the given parameters

Procedure

APOC Core

apoc.cypher.runMany

- runs each semicolon separated statement and returns summary

Procedure

APOC Core

apoc.cypher.parallel

- executes fragments in parallel through a list defined in paramMap with a key keyList

Procedure

APOC Full

apoc.cypher.parallel2

- executes fragments in parallel batches through a list defined in paramMap with a key keyList

Procedure

APOC Full

apoc.cypher.mapParallel

- executes fragment in parallel batches with the list segments being assigned to _

Procedure

APOC Full

apoc.cypher.mapParallel2

- executes fragment in parallel batches with the list segments being assigned to _

Procedure

APOC Full

apoc.cypher.runFirstColumn

Function

APOC Core

apoc.cypher.runFirstColumnMany

- executes statement with given parameters, returns first column only collected into a list, params are available as identifiers

Function

APOC Core

apoc.cypher.runFirstColumnSingle

- executes statement with given parameters, returns first element of the first column only, params are available as identifiers

Function

APOC Core

Example: Fast Node-Counts by Label

We can quickly compute the number of nodes for a specific label using the count function, but only if that’s the only single thing in the query. For example:

MATCH (:Person) RETURN count(*);

We can also combine several with UNION ALL:

Works
MATCH (:Person) RETURN count(*)
UNION ALL
MATCH (:Movie) RETURN count(*);

But we can’t do the same thing using the WITH clause:

Doesn’t work
MATCH (:Person)
WITH count(*) as people
MATCH (:Movie) RETURN people, count(*) as movies;

This query will work out the count by iterating over all nodes, which is a very slow operation

We can use apoc.cypher.run to construct the COUNT() statements and run each of them individually, so it completes in a few ms.

CALL db.labels() yield label
CALL apoc.cypher.run("match (:`"+label+"`) return count(*) as count", null) yield value
return label, value.count as count

You can use a similar approach to get the property-keys per label:

CALL db.labels() yield label
CALL apoc.cypher.run("MATCH (n:`"+label+"`) RETURN keys(n) as keys LIMIT 1",null) yield value
RETURN label, value.keys as keys