YMatrix
Quick Start
Connecting
Benchmarks
Deployment
Data Usage
Manage Clusters
Upgrade
Global Maintenance
Expansion
Monitoring
Security
Best Practice
Technical Principles
Data Type
Storage Engine
Execution Engine
Streaming Engine(Domino)
MARS3 Index
Extension
Advanced Features
Advanced Query
Federal Query
Grafana
Backup and Restore
Disaster Recovery
Graph Database
Introduction
Clauses
Functions
Advanced
Guide
Performance Tuning
Troubleshooting
Tools
Configuration Parameters
SQL Reference
The UNWIND clause in Cypher transforms a list into a sequence of individual rows. Each element in the input list becomes a separate row, with the specified variable bound to that element. If the expression evaluates to NULL, UNWIND produces a single row with the variable set to NULL. If the expression evaluates to an empty list, UNWIND produces no rows. This behavior is consistent across AGE.
UNWIND is especially useful when processing list-valued properties on vertices or edges, or when iterating over a collection of values within a query.
The following examples use this reference dataset:
SELECT * FROM cypher('cypher_unwind', $$
CREATE (n {name: 'node1', a: [1, 2, 3]}),
(m {name: 'node2', a: [4, 5, 6]}),
(o {name: 'node3', a: [7, 8, 9]}),
(n)-[:KNOWS]->(m),
(m)-[:KNOWS]->(o)
$$) AS (i agtype);
This example demonstrates the simplest use of UNWIND: expanding a literal list of integers into individual rows.
SELECT * FROM cypher('cypher_unwind', $$
UNWIND [1, 2, 3] AS i
RETURN i
$$) AS (i agtype);
i
---
1
2
3
(3 rows)
This example shows how to use UNWIND to process a list-valued property on nodes, using the reference data.
SELECT * FROM cypher('cypher_unwind', $$
MATCH (n)
WITH n.a AS a
UNWIND a AS i
RETURN *
$$) AS (i agtype, j agtype);
i | j
-----------+---
[1, 2, 3] | 1
[1, 2, 3] | 2
[1, 2, 3] | 3
[4, 5, 6] | 4
[4, 5, 6] | 5
[4, 5, 6] | 6
[7, 8, 9] | 7
[7, 8, 9] | 8
[7, 8, 9] | 9
(9 rows)
UNWIND can be nested to flatten deeply nested lists.
SELECT * FROM cypher('cypher_unwind', $$
WITH [[1, 2], [3, 4], 5] AS nested
UNWIND nested AS x
UNWIND x AS y
RETURN y
$$) AS (i agtype);
i
---
1
2
3
4
5
(5 rows)
nodes()UNWIND can be used with path functions such as nodes() to process individual vertices in a path.
SELECT * FROM cypher('cypher_unwind', $$
MATCH p=(n)-[:KNOWS]->(m)
UNWIND nodes(p) AS node
RETURN node
$$) AS (i agtype);
i
-----------------------------------------------------------------------------------------------
{"id": 281474976710657, "label": "", "properties": {"a": [1, 2, 3], "name": "node1"}}::vertex
{"id": 281474976710658, "label": "", "properties": {"a": [4, 5, 6], "name": "node2"}}::vertex
{"id": 281474976710658, "label": "", "properties": {"a": [4, 5, 6], "name": "node2"}}::vertex
{"id": 281474976710659, "label": "", "properties": {"a": [7, 8, 9], "name": "node3"}}::vertex
(4 rows)
relationships()Similarly, UNWIND can be used with relationships() to process individual relationships in a path.
SELECT * FROM cypher('cypher_unwind', $$
MATCH p=(n)-[:KNOWS]->(m)
UNWIND relationships(p) AS relation
RETURN relation
$$) AS (i agtype);
i
---------------------------------------------------------------------------------------------------------------------------
{"id": 844424930131969, "label": "KNOWS", "end_id": 281474976710658, "start_id": 281474976710657, "properties": {}}::edge
{"id": 844424930131970, "label": "KNOWS", "end_id": 281474976710659, "start_id": 281474976710658, "properties": {}}::edge
(2 rows)
relationships() and Explicit Path UnwindingThis example demonstrates unwinding relationships from a path that is itself explicitly wrapped in a list.
SELECT * FROM cypher('cypher_unwind', $$
MATCH p=({name:'node1'})-[e:KNOWS*]->({name:'node3'})
UNWIND [p] AS path
UNWIND relationships(path) AS edge
RETURN edge
$$) AS (i agtype);
i
---------------------------------------------------------------------------------------------------------------------------
{"id": 844424930131969, "label": "KNOWS", "end_id": 281474976710658, "start_id": 281474976710657, "properties": {}}::edge
{"id": 844424930131970, "label": "KNOWS", "end_id": 281474976710659, "start_id": 281474976710658, "properties": {}}::edge
(2 rows)
UNWIND can be combined with SET to update properties based on the unwound values.
SELECT * FROM cypher('cypher_unwind', $$
MATCH p=(n)-[:KNOWS]->(m)
UNWIND nodes(p) AS node
SET node.type = 'vertex'
$$) AS (i agtype);
i
---
(0 rows)
This example illustrates how UNWIND handles NULL. Understanding this behavior is critical when working with optional list properties or expressions that may evaluate to NULL.
SELECT * FROM cypher('cypher_unwind', $$
UNWIND NULL AS i
RETURN i
$$) AS (i agtype);
i
---
(1 row)