UNWIND
The UNWIND
clause makes it possible to transform any list back into individual rows.
These lists can be parameters that were passed in, previously collect
-ed result, or other list expressions.
Neo4j does not guarantee the row order produced by |
Common usage of the UNWIND
clause:
-
Create distinct lists.
-
Create data from parameter lists that are provided to the query.
The |
Unwinding a list
We want to transform the literal list into rows named x
and return them.
UNWIND [1, 2, 3, null] AS x
RETURN x, 'val' AS y
Each value of the original list — including null
— is returned as an individual row.
x | y |
---|---|
|
|
|
|
|
|
|
|
|
Creating a distinct list
We want to transform a list of duplicates into a set using DISTINCT
.
WITH [1, 1, 2, 2] AS coll
UNWIND coll AS x
WITH DISTINCT x
RETURN collect(x) AS setOfVals
Each value of the original list is unwound and passed through DISTINCT
to create a unique set.
setOfVals |
---|
|
|
Using UNWIND
with any expression returning a list
Any expression that returns a list may be used with UNWIND
.
WITH
[1, 2] AS a,
[3, 4] AS b
UNWIND (a + b) AS x
RETURN x
The two lists — a and b — are concatenated to form a new list, which is then operated upon by UNWIND
.
x |
---|
|
|
|
|
|
Using UNWIND
with a list of lists
Multiple UNWIND
clauses can be chained to unwind nested list elements.
WITH [[1, 2], [3, 4], 5] AS nested
UNWIND nested AS x
UNWIND x AS y
RETURN y
The first UNWIND
results in three rows for x
, each of which contains an element of the original list (two of which are also lists); namely, [1, 2]
, [3, 4]
, and 5
.
The second UNWIND
then operates on each of these rows in turn, resulting in five rows for y
.
y |
---|
|
|
|
|
|
|
Using UNWIND
with an empty list
Using an empty list with UNWIND
will produce no rows, irrespective of whether or not any rows existed beforehand, or whether or not other values are being projected.
Essentially, UNWIND []
reduces the number of rows to zero, and thus causes the query to cease its execution, returning no results.
This has value in cases such as UNWIND v
, where v
is a variable from an earlier clause that may or may not be an empty list — when it is an empty list, this will behave just as a MATCH
that has no results.
UNWIND [] AS empty
RETURN 'literal_that_is_not_returned'
|
|
Rows: 0 |
To avoid inadvertently using UNWIND
on an empty list, CASE
may be used to replace an empty list with a null
:
WITH [] AS list
UNWIND
CASE
WHEN list = [] THEN [null]
ELSE list
END AS emptylist
RETURN emptylist
Using UNWIND
with an expression that is not a list
Using UNWIND
on an expression that does not return a list, will return the same result as using UNWIND
on a list that just contains that expression.
As an example, UNWIND 5
is effectively equivalent to UNWIND[5]
.
The exception to this is when the expression returns null
— this will reduce the number of rows to zero, causing it to cease its execution and return no results.
UNWIND null AS x
RETURN x, 'some_literal'
|
|
|
Creating nodes from a list parameter
Create a number of nodes and relationships from a parameter-list without using FOREACH
.
{
"events" : [ {
"year" : 2014,
"id" : 1
}, {
"year" : 2014,
"id" : 2
} ]
}
UNWIND $events AS event
MERGE (y:Year {year: event.year})
MERGE (y)<-[:IN]-(e:Event {id: event.id})
RETURN e.id AS x ORDER BY x
Each value of the original list is unwound and passed through MERGE
to find or create the nodes and relationships.
x |
---|
|
|
Rows: 2 |