The aggregation $unwind operator in MongoDB is used to split up an array field into separate documents for each element in the array, In other words, it deconstructs an array field from the input documents to output a document for each element. In this article, we will explore more about the $unwind
aggregation operator in MongoDB, its usage with the examples.
This article is part of our MongoDB Tutorial Guide, the guide includes the MongoDB concepts and the most used examples with tips and tricks.
1. Syntax of the $unwind operator
The structure of the $unwind
operator used in MongoDB is as follows.
# Syntax
{
$unwind:
{
path: field,
includeArrayIndex: stringValue,
preserveNullAndEmptyArrays: booleanValue
}
}
Here,
path
is a required parameter that specifies the array field to unwind. It can be used as a dot-separated path to the field, which is useful for nested arrays or fields in subdocuments.includeArrayIndex
is the optional parameter. It includes the index of each element in the array as a separate field in the output documents. If we use this option, we also need to give the field name that will store the index value.preserveNullAndEmptyArrays
is an optional parameter of the$unwind
operator, handle documents that have null or empty arrays for the field being unwound. If set to true, these documents will be included in the output with an empty array or null value for the unwound field.
2. MongoDB $unwind operator Usage
The MongoDB $unwind operator is used to deconstructing an array field from the input documents to output a document for each element. The simple example of the $unwind
operator is to deconstruct the simple array field. Let’s consider the following single document.
# Adding array field
db.student1.insertOne({ "_id" : 1,
"name" : "stefan", "course": [ "MongoDB", "Java", "Python"] })
The $unwind
operator is applied over this document to transform the array into a separate document. Here, the $unwind
operator creates a new document for each course that a student is taking.
# Usage of $unwind operator
db.student1.aggregate([ { $unwind: "$course" } ])
The output shows the resultant documents below.
3. By Using $unwind preserveNullEmptyArrays option
By default, the $unwind
operator removes documents that have empty arrays. However, we can use the preserveNullAndEmptyArrays
option to keep these documents in the result set. For this, we have created a separate collection with some empty arrays.
# Usage of preserveNullAndEmptyArrays option
db.Student2.insertMany([
{ "_id" : 1, "name" : "Emily", age: 24, "course": [ "Python", "Java", "MongoDB"] },
{ "_id" : 2, "name" : "Alex", price: 21, "course" : [ ] },
{ "_id" : 3, "name" : "David", price: 22, "course": "MongoDB" },
{ "_id" : 4, "name" : "Harry" , price: 20 },
{ "_id" : 5, "name" : "Marrie", price: 23, "course" : null }
])
Now, we will use the $unwind
operator over these documents. Here, we have set the query where the $unwind
operator is called. The path
option specifies the name of the field to unwind, which is course
. The preserveNullAndEmptyArrays
option includes documents in the result set even if the course
array field is null or empty.
# $unwind operator usage over documents
db.Student2.aggregate([
{ $unwind: { path: "$course", preserveNullAndEmptyArrays: true } }
])
The output displayed a new set of documents that include all the fields from the original document, with the course
array field replaced by a single course. We can also see the documents which have no courses appear with a null or empty course
field.
4. By Using includeArrayIndex option
In addition, the $unwind
operator also has an includeArrayIndex
option, which can be used to include the index of the array element being unwound.
We have utilized the collection that is used in the prior example. So, consider the query where the $unwind
operator unwinds the course
field as the path option is set with this field. Then, the includeArrayIndex
option is deployed to add a new field to the output documents called arrayIndex
. It contains the index of the course in the original course
array.
# Usage of includeArrayIndex option
db.Student2.aggregate([
{ $unwind: { path: "$course", includeArrayIndex: "arrayIndex" } }
])
The output generates a new set of documents with the arrayIndex
field indicating the position of the course in the original array.
5. $unwind operator on an embedded array
The $unwind operator in MongoDB can be used to unwind arrays that are embedded inside other arrays or objects. We have created a new collection for this example where the documents contain the embedded array field.
# Create Collection
db.student3.insertMany([
{
_id: "1",
"groups" : [
{
"name" : "John",
"course": [ "MongoDB", "Java"]
},
{
"name" : "Bella",
"course": [ "PHP", "Python"]
}
]
},
{
_id: "2",
"groups" : [
{
"name" : "Caroline",
"course": [ "C++", "Csharp"]
},
{
"name" : "Alice",
"course": [ "Perl", "Data Science"]
}
]
}
])
Here, we used the $unwind
operator for the groups
embedded array to deconstruct. For each element of the embedded array, the $unwind
operator generates a new document while maintaining the parent document’s structure.
# Usage of $unwind operator on embedded array
db.student3.aggregate({$unwind: "$groups"}).pretty()
The output is retrieved where each subdocument is in a separate document.
If you want to learn about MongoDB embedded or reference relationships, you can use the following link.
6. Conclusion
In conclusion, The $unwin operator in MongoDB deconstructs an array field from the input documents to output a document for each element. By specifying the array field to unwind, including the array index, and preserving null or empty arrays, we can easily customize the behavior of the operator to fit the specific requirements.
More details about this topic can be found here.