Files
next.orly.dev/.claude/skills/cypher/references/syntax-reference.md
2025-12-03 10:25:31 +00:00

9.6 KiB

Cypher Syntax Reference

Complete syntax reference for Neo4j Cypher query language.

Clause Reference

Reading Clauses

MATCH

Finds patterns in the graph.

// Basic node match
MATCH (n:Label)

// Match with properties
MATCH (n:Label {key: value})

// Match relationships
MATCH (a)-[r:RELATES_TO]->(b)

// Match path
MATCH path = (a)-[*1..3]->(b)

OPTIONAL MATCH

Like MATCH but returns NULL for non-matches (LEFT OUTER JOIN).

MATCH (a:Person)
OPTIONAL MATCH (a)-[:KNOWS]->(b:Person)
RETURN a.name, b.name  // b.name may be NULL

WHERE

Filters results.

// Comparison operators
WHERE n.age > 21
WHERE n.age >= 21
WHERE n.age < 65
WHERE n.age <= 65
WHERE n.name = 'Alice'
WHERE n.name <> 'Bob'

// Boolean operators
WHERE n.age > 21 AND n.active = true
WHERE n.age < 18 OR n.age > 65
WHERE NOT n.deleted

// NULL checks
WHERE n.email IS NULL
WHERE n.email IS NOT NULL

// Pattern predicates
WHERE (n)-[:KNOWS]->(:Person)
WHERE NOT (n)-[:BLOCKED]->()
WHERE exists((n)-[:FOLLOWS]->())

// String predicates
WHERE n.name STARTS WITH 'A'
WHERE n.name ENDS WITH 'son'
WHERE n.name CONTAINS 'li'
WHERE n.name =~ '(?i)alice.*'  // Case-insensitive regex

// List predicates
WHERE n.status IN ['active', 'pending']
WHERE any(x IN n.tags WHERE x = 'important')
WHERE all(x IN n.scores WHERE x > 50)
WHERE none(x IN n.errors WHERE x IS NOT NULL)
WHERE single(x IN n.items WHERE x.primary = true)

Writing Clauses

CREATE

Creates nodes and relationships.

// Create node
CREATE (n:Label {key: value})

// Create multiple nodes
CREATE (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})

// Create relationship
CREATE (a)-[r:KNOWS {since: 2020}]->(b)

// Create path
CREATE p = (a)-[:KNOWS]->(b)-[:KNOWS]->(c)

MERGE

Find or create pattern. Critical for idempotency.

// MERGE node
MERGE (n:Label {key: $uniqueKey})

// MERGE with ON CREATE / ON MATCH
MERGE (n:Person {email: $email})
ON CREATE SET n.created = timestamp(), n.name = $name
ON MATCH SET n.accessed = timestamp()

// MERGE relationship (both nodes must exist or be in scope)
MERGE (a)-[r:KNOWS]->(b)
ON CREATE SET r.since = date()

MERGE Gotcha: MERGE on a pattern locks the entire pattern. For relationships, MERGE each node first:

// CORRECT
MERGE (a:Person {id: $id1})
MERGE (b:Person {id: $id2})
MERGE (a)-[:KNOWS]->(b)

// RISKY - may create duplicate nodes
MERGE (a:Person {id: $id1})-[:KNOWS]->(b:Person {id: $id2})

SET

Updates properties.

// Set single property
SET n.name = 'Alice'

// Set multiple properties
SET n.name = 'Alice', n.age = 30

// Set from map (replaces all properties)
SET n = {name: 'Alice', age: 30}

// Set from map (adds/updates, keeps existing)
SET n += {name: 'Alice'}

// Set label
SET n:NewLabel

// Remove property
SET n.obsolete = null

DELETE / DETACH DELETE

Removes nodes and relationships.

// Delete relationship
MATCH (a)-[r:KNOWS]->(b)
DELETE r

// Delete node (must have no relationships)
MATCH (n:Orphan)
DELETE n

// Delete node and all relationships
MATCH (n:Person {name: 'Bob'})
DETACH DELETE n

REMOVE

Removes properties and labels.

// Remove property
REMOVE n.temporary

// Remove label
REMOVE n:OldLabel

Projection Clauses

RETURN

Specifies output.

// Return nodes
RETURN n

// Return properties
RETURN n.name, n.age

// Return with alias
RETURN n.name AS name, n.age AS age

// Return all
RETURN *

// Return distinct
RETURN DISTINCT n.category

// Return expression
RETURN n.price * n.quantity AS total

WITH

Passes results between query parts. Critical for multi-part queries.

// Filter and pass
MATCH (n:Person)
WITH n WHERE n.age > 21
RETURN n

// Aggregate and continue
MATCH (n:Person)-[:BOUGHT]->(p:Product)
WITH n, count(p) AS purchases
WHERE purchases > 5
RETURN n.name, purchases

// Order and limit mid-query
MATCH (n:Person)
WITH n ORDER BY n.age DESC LIMIT 10
MATCH (n)-[:LIVES_IN]->(c:City)
RETURN n.name, c.name

WITH resets scope: Variables not listed in WITH are no longer available.

ORDER BY

Sorts results.

ORDER BY n.name                    // Ascending (default)
ORDER BY n.name ASC               // Explicit ascending
ORDER BY n.name DESC              // Descending
ORDER BY n.lastName, n.firstName  // Multiple fields
ORDER BY n.priority DESC, n.name  // Mixed

SKIP and LIMIT

Pagination.

// Skip first 10
SKIP 10

// Return only 20
LIMIT 20

// Pagination
ORDER BY n.created_at DESC
SKIP $offset LIMIT $pageSize

Sub-queries

CALL (Subquery)

Execute subquery for each row.

MATCH (p:Person)
CALL {
  WITH p
  MATCH (p)-[:BOUGHT]->(prod:Product)
  RETURN count(prod) AS purchaseCount
}
RETURN p.name, purchaseCount

UNION

Combine results from multiple queries.

MATCH (n:Person) RETURN n.name AS name
UNION
MATCH (n:Company) RETURN n.name AS name

// UNION ALL keeps duplicates
MATCH (n:Person) RETURN n.name AS name
UNION ALL
MATCH (n:Company) RETURN n.name AS name

Control Flow

FOREACH

Iterate over list, execute updates.

// Set property on path nodes
MATCH path = (a)-[*]->(b)
FOREACH (n IN nodes(path) | SET n.visited = true)

// Conditional operation (common pattern)
OPTIONAL MATCH (target:Node {id: $id})
FOREACH (_ IN CASE WHEN target IS NOT NULL THEN [1] ELSE [] END |
  CREATE (source)-[:LINKS_TO]->(target)
)

CASE

Conditional expressions.

// Simple CASE
RETURN CASE n.status
  WHEN 'active' THEN 'A'
  WHEN 'pending' THEN 'P'
  ELSE 'X'
END AS code

// Generic CASE
RETURN CASE
  WHEN n.age < 18 THEN 'minor'
  WHEN n.age < 65 THEN 'adult'
  ELSE 'senior'
END AS category

Operators

Comparison

Operator Description
= Equal
<> Not equal
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
IS NULL Is null
IS NOT NULL Is not null

Boolean

Operator Description
AND Logical AND
OR Logical OR
NOT Logical NOT
XOR Exclusive OR

String

Operator Description
STARTS WITH Prefix match
ENDS WITH Suffix match
CONTAINS Substring match
=~ Regex match

List

Operator Description
IN List membership
+ List concatenation

Mathematical

Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulo
^ Exponentiation

Functions

Aggregation

count(*)              // Count rows
count(n)              // Count non-null
count(DISTINCT n)     // Count unique
sum(n.value)          // Sum
avg(n.value)          // Average
min(n.value)          // Minimum
max(n.value)          // Maximum
collect(n)            // Collect to list
collect(DISTINCT n)   // Collect unique
stDev(n.value)        // Standard deviation
percentileCont(n.value, 0.5)  // Median

Scalar

// Type functions
id(n)                 // Internal node ID (deprecated, use elementId)
elementId(n)          // Element ID string
labels(n)             // Node labels
type(r)               // Relationship type
properties(n)         // Property map

// Math
abs(x)
ceil(x)
floor(x)
round(x)
sign(x)
sqrt(x)
rand()                // Random 0-1

// String
size(str)             // String length
toLower(str)
toUpper(str)
trim(str)
ltrim(str)
rtrim(str)
replace(str, from, to)
substring(str, start, len)
left(str, len)
right(str, len)
split(str, delimiter)
reverse(str)
toString(val)

// Null handling
coalesce(val1, val2, ...)  // First non-null
nullIf(val1, val2)         // NULL if equal

// Type conversion
toInteger(val)
toFloat(val)
toBoolean(val)
toString(val)

List Functions

size(list)            // List length
head(list)            // First element
tail(list)            // All but first
last(list)            // Last element
range(start, end)     // Create range [start..end]
range(start, end, step)
reverse(list)
keys(map)             // Map keys as list
values(map)           // Map values as list

// List predicates
any(x IN list WHERE predicate)
all(x IN list WHERE predicate)
none(x IN list WHERE predicate)
single(x IN list WHERE predicate)

// List manipulation
[x IN list WHERE predicate]           // Filter
[x IN list | expression]              // Map
[x IN list WHERE pred | expr]         // Filter and map
reduce(s = initial, x IN list | s + x) // Reduce

Path Functions

nodes(path)           // Nodes in path
relationships(path)   // Relationships in path
length(path)          // Number of relationships
shortestPath((a)-[*]-(b))
allShortestPaths((a)-[*]-(b))

Temporal Functions

timestamp()           // Current Unix timestamp (ms)
datetime()            // Current datetime
date()                // Current date
time()                // Current time
duration({days: 1, hours: 12})

// Components
datetime().year
datetime().month
datetime().day
datetime().hour

// Parsing
date('2024-01-15')
datetime('2024-01-15T10:30:00Z')

Spatial Functions

point({x: 1, y: 2})
point({latitude: 37.5, longitude: -122.4})
distance(point1, point2)

Comments

// Single line comment

/* Multi-line
   comment */

Transaction Control

// In procedures/transactions
:begin
:commit
:rollback

Parameter Syntax

// Parameter reference
$paramName

// In properties
{key: $value}

// In WHERE
WHERE n.id = $id

// In expressions
RETURN $multiplier * n.value