3.3.6. UNWIND

UNWIND expands a list into a sequence of rows.

3.3.6.1. Introduction

With UNWIND, you can transform any list back into individual rows. These lists can be parameters that were passed in, previously collect -ed result or other list expressions.

One common usage of unwind is to create distinct lists. Another is to create data from parameter lists that are provided to the query.

UNWIND requires you to specify a new name for the inner values.

3.3.6.2. Unwinding a list

We want to transform the literal list into rows named x and return them.

Query. 

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.

Table 3.76. Result
x y

4 rows

1

"val"

2

"val"

3

"val"

<null>

"val"

Try this query live.  none UNWIND [1, 2, 3, null] AS x RETURN x, 'val' AS y

3.3.6.3. Creating a distinct list

We want to transform a list of duplicates into a set using DISTINCT.

Query. 

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.

Table 3.77. Result
setOfVals

1 row

[1,2]

Try this query live.  none WITH [1, 1, 2, 2] AS coll UNWIND coll AS x WITH DISTINCT x RETURN collect(x) AS setOfVals

3.3.6.4. Using UNWIND with any expression returning a list

Any expression that returns a list may be used with UNWIND.

Query. 

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.

Table 3.78. Result
x

4 rows

1

2

3

4

Try this query live.  none WITH [1, 2] AS a, [3, 4] AS b UNWIND (a + b) AS x RETURN x

3.3.6.5. Using UNWIND with a list of lists

Multiple UNWIND clauses can be chained to unwind nested list elements.

Query. 

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.

Table 3.79. Result
y

5 rows

1

2

3

4

5

Try this query live.  none WITH [[1, 2], [3, 4], 5] AS nested UNWIND nested AS x UNWIND x AS y RETURN y

3.3.6.6. 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.

Query. 

UNWIND [] AS empty
RETURN empty, 'literal_that_is_not_returned'

Table 3.80. Result
(empty result)

0 rows

Try this query live.  none UNWIND [] AS empty RETURN empty, 'literal_that_is_not_returned'

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

3.3.6.7. Using UNWIND with an expression that is not a list

Attempting to use UNWIND on an expression that does not return a list — such as UNWIND 5 — will cause an error. 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.

Query. 

UNWIND NULL AS x
RETURN x, 'some_literal'

Table 3.81. Result
(empty result)

0 rows

Try this query live.  none UNWIND null AS x RETURN x, 'some_literal'

3.3.6.8. Creating nodes from a list parameter

Create a number of nodes and relationships from a parameter-list without using FOREACH.

Parameters. 

{
  "events" : [ {
    "year" : 2014,
    "id" : 1
  }, {
    "year" : 2014,
    "id" : 2
  } ]
}

Query. 

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.

Table 3.82. Result
x

2 rows Nodes created: 3 Relationships created: 2 Properties set: 3 Labels added: 3

1

2

Try this query live.  none 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