Pattern Comprehensions in Neo4j are a powerful way to “inline” queries inside a single Cypher statement.
They let you collect lists of related nodes or values while applying filters, without needing a separate MATCH.
🔹 Syntax
-
pattern → a traversal pattern like
(u)-[:WORKS_ON]->(p) -
expression → usually the starting node
-
WHERE filter → optional condition
-
projection → what to return (node, property, or expression)
1️⃣ Example Dataset
2️⃣ Collect Alice’s projects with filters
✅ Output:
| user | projects |
|---|---|
| Alice | ["ProjectX", "ProjectY"] |
3️⃣ Filter by relationship property
✅ Output:
| recent_projects |
|---|
| ["ProjectX"] |
4️⃣ Nested properties from relationships
✅ Output:
| details |
|---|
| [{project:"ProjectX", year:2023}, {project:"ProjectY", year:2022}] |
5️⃣ Aggregation inside comprehension
✅ Output:
| p.name | team_size |
|---|---|
| ProjectX | 2 |
| ProjectY | 2 |
👉 When to use Pattern Comprehensions?
-
To inline subqueries without extra MATCH/OPTIONAL MATCH.
-
To filter and project lists of related nodes/relationships.
-
To keep queries compact & expressive.
Let’s now look at Subqueries in Neo4j — introduced in Neo4j 4.x — they’re very useful when you need multi-step logic or want to scope variables.
🔹 Subqueries with CALL { ... }
A subquery is like a "query inside a query".
It’s wrapped inside CALL { ... } and returns a result that the outer query can continue using.
1️⃣ Syntax
2️⃣ Example Dataset (same as before)
3️⃣ Example – Get Alice’s recent projects (subquery version)
✅ Output:
| u.name | recent_projects |
|---|---|
| Alice | ["ProjectX"] |
4️⃣ Example – Aggregations per group
✅ Output:
| p.name | team_size |
|---|---|
| ProjectX | 2 |
| ProjectY | 1 |
5️⃣ Example – Optional subquery
You can also make the whole subquery optional:
✅ Output:
| u.name | all_projects |
|---|---|
| Alice | ["ProjectX", "ProjectY"] |
🔹 When to use Subqueries vs Pattern Comprehensions?
| Pattern Comprehension | Subquery (CALL {}) |
|---|---|
| Inline filtering & projection | Multi-step logic |
Works inside RETURN only | Can be used anywhere in query |
| Good for small filters/lists | Good for aggregations, multiple matches |
| Lightweight, compact | More verbose but powerful |
👉 So, if you just need a list with filters → use pattern comprehension.
👉 If you need aggregation, optional logic, or multiple steps → use subqueries.
Let’s dig into List Operations in Cypher — especially two powerful clauses: UNWIND and WITH.
🔹 1. UNWIND – Turn a list into rows
UNWIND takes a list and expands it into individual rows.
Think of it as the opposite of collect().
Example 1: Simple UNWIND
✅ Output:
| num |
|---|
| 1 |
| 2 |
| 3 |
Example 2: Create multiple nodes from a list
👉 Creates 3 users: Alice, Bob, Charlie.
Example 3: UNWIND with properties
👉 Creates 2 users with properties.
🔹 2. WITH – Pipeline / pass variables
WITH is like a pipe: it passes variables to the next part of the query.
Also used for:
-
Aggregations
-
Aliases
-
Ordering, limiting
-
Scoping variables
Example 1: Simple WITH
✅ Renames u.name → username.
Example 2: Filtering with WITH
✅ Finds users who work on more than 1 project.
Example 3: Chaining WITH
✅ Collects all users into a list per project.
Output:
| p.name | team |
|---|---|
| ProjectX | ["Alice", "Bob"] |
| ProjectY | ["Alice"] |
🔹 3. Combining UNWIND + WITH
Example – Split list per user
👉 For each user, creates 2 skill relationships: Python, Neo4j.
✅ Key Takeaways
-
UNWIND→ Break a list into rows (for iteration / creation). -
WITH→ Pipe, filter, rename, aggregate, and control query flow. -
Together → They let you transform data flexibly.
Comments
Post a Comment