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:
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:
-
A Movie is retrieved that Tom Hanks acted in.
-
The languages property, which is a list is unwound and each value is referenced as lang.
-
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.
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:
-
Retrieves all Movie nodes.
-
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.
-
Then we use the element of the list to find all Movies that use that language.
-
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.
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
.