Unwinding Lists

Using UNWIND

You have learned that in a query, you can create lists of nodes, strings, or numbers using collect(). Sometimes it is useful to collect elements as intermediate results that are passed on to a later part of a query. For example, the graph you are working with contains languages and countries lists for each Movie node. If you wanted to refactor the graph to create a Language node and associate it with any Movie node that had that particular language in its languages list, you could unwind the list to access each element in the list.

UNWIND returns a row for each element of a list.

Here is an example:

cypher
MATCH (m:Movie)-[:ACTED_IN]-(a:Actor)
WHERE a.name = 'Tom Hanks'
UNWIND m.languages AS lang
RETURN m.title AS movie,
m.languages AS languages,
lang AS language

In this query:

  1. A Movie is retrieved that Tom Hanks acted in.

  2. The languages property, which is a list is unwound and each value is referenced as lang.

  3. The rows returned will be the movie title and the languages property repeated for multiple rows and the lang value.

In this code, you could imagine that you could create a Language node with a name property which is lang.

Let’s now look at a more useful example.

cypher
MATCH (m:Movie)
UNWIND m.languages AS lang
WITH m, trim(lang) AS language
// this automatically, makes the language distinct because it's a grouping key
WITH language, collect(m.title) AS movies
RETURN language, movies[0..10]

This query:

  1. Retrieves all Movie nodes.

  2. For each Movie node, it unwinds the languages list to create a list called lang. Notice that we use the trim() function to ensure there are no extraneous whitespace characters in the language name.

  3. Then we use the element of the list to find all Movies that use that language.

  4. Finally, we return a row that contains each language name and the list of up to 10 movie titles for that language.

Check your understanding

1. Using UNWIND

Here is a query to return the title of a movie and language pair for any Tom Hanks movie that has exactly two languages associated with it. That is each movie will have two rows, the title is repeated and then each language for that title. How do you complete this query to create a lang value that is an element of the languages list? Once you have selected your option, click the Check Results query button to continue.

cypher
MATCH (m:Movie)-[:ACTED_IN]-(a:Actor)
WHERE a.name = 'Tom Hanks'
AND size(m.languages) = 2
/*select:UNWIND m.languages AS lang*/
RETURN m.title AS movie,lang AS languages
  • unwind(m.languages) AS lang

  • UNWIND m AS lang

  • UNWIND m.languages AS lang

  • UNWIND m.lang

Hint

UNWIND is always done on a list and it returns a row for each value in the list.

Solution

The correct answer is: UNWIND m.languages AS lang. The languages property of a Movie node is a list so you can unwind it.

The other two UNWIND clauses do not operation on a list.

There is no unwind() function in Cypher.

2. Using UNWIND

What type of data can UNWIND be used for?

  • ❏ String

  • ✓ List of strings

  • ❏ Map

  • ✓ List of numerics

Hint

The UNWIND keyword in Cypher is used to transform a collection into a sequence of rows for further processing.

Solution

The answers are List of strings and List of numerics.

Summary

In this lesson, you learned how UNWIND can be used to create intermediate results that can be used for pipelining queries.

In the next challenge, you will modify a query that uses UNWIND.