- Reference >
- Operators >
- Aggregation Pipeline Operators >
- Pipeline Aggregation Stages >
- $unwind (aggregation)
$unwind (aggregation)¶
On this page
Definition¶
-
$unwind
¶ Deconstructs an array field from the input documents to output a document for each element. Each output document is the input document with the value of the array field replaced by the element.
The
$unwind
stage has one of two syntaxes:The operand is a field path:
{ $unwind: <field path> }
To specify a field path, prefix the field name with a dollar sign
$
and enclose in quotes.The operand is a document:
New in version 3.2.
{ $unwind: { path: <field path>, includeArrayIndex: <string>, preserveNullAndEmptyArrays: <boolean> } }
Field Type Description path
string Field path to an array field. To specify a field path, prefix the field name with a dollar sign $
and enclose in quotes.includeArrayIndex
string Optional. The name of a new field to hold the array index of the element. The name cannot start with a dollar sign $
.preserveNullAndEmptyArrays
boolean Optional. If
true
, if thepath
is null, missing, or an empty array,$unwind
outputs the document. Iffalse
,$unwind
does not output a document if thepath
is null, missing, or an empty array.The default value is
false
.
Behaviors¶
Non-Array Field Path¶
Changed in version 3.2: $unwind
stage no longer errors on non-array operands. If
the operand does not resolve to an array but is not missing, null,
or an empty array, $unwind
treats the operand as a
single element array.
Previously, if a value in the field specified by the field path is
not an array, db.collection.aggregate()
generates an
error.
Missing Field¶
If you specify a path for a field that does not exist in an input
document or the field is an empty array, $unwind
, by
default, ignores the input document and will not output documents for
that input document.
New in version 3.2: To output documents where the array field is missing, null or an
empty array, use the option preserveNullAndEmptyArrays
.
Examples¶
Unwind Array¶
Consider an inventory
with the following document:
{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }
The following aggregation uses the $unwind
stage to output
a document for each element in the sizes
array:
db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
The operation returns the following results:
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }
Each document is identical to the input document except for the value
of the sizes
field which now holds a value from the original
sizes
array.
includeArrayIndex
and preserveNullAndEmptyArrays
¶
New in version 3.2.
A collection inventory
has the following documents:
{ "_id" : 1, "item" : "ABC", "sizes": [ "S", "M", "L"] }
{ "_id" : 2, "item" : "EFG", "sizes" : [ ] }
{ "_id" : 3, "item" : "IJK", "sizes": "M" }
{ "_id" : 4, "item" : "LMN" }
{ "_id" : 5, "item" : "XYZ", "sizes" : null }
The following $unwind
operations are equivalent and return
a document for each element in the sizes
field. If the sizes
field does not resolve to an array but is not missing, null, or an
empty array, $unwind
treats the non-array operand as a
single element array.
db.inventory.aggregate( [ { $unwind: "$sizes" } ] )
db.inventory.aggregate( [ { $unwind: { path: "$sizes" } } ] )
The operation returns the following documents:
{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }
The following $unwind
operation uses the
includeArrayIndex
option to output also the array index of the
array element.
db.inventory.aggregate( [ { $unwind: { path: "$sizes", includeArrayIndex: "arrayIndex" } } ] )
The operation unwinds the sizes
array and includes the array index
of the array index in the new arrayIndex
field. If the sizes
field does not resolve to an array but is not missing, null, or an
empty array, the arrayIndex
field is null
.
{ "_id" : 1, "item" : "ABC", "sizes" : "S", "arrayIndex" : NumberLong(0) }
{ "_id" : 1, "item" : "ABC", "sizes" : "M", "arrayIndex" : NumberLong(1) }
{ "_id" : 1, "item" : "ABC", "sizes" : "L", "arrayIndex" : NumberLong(2) }
{ "_id" : 3, "item" : "IJK", "sizes" : "M", "arrayIndex" : null }
The following $unwind
operation uses the
preserveNullAndEmptyArrays
option to include in the output those
documents where sizes
field is missing, null or an empty array.
db.inventory.aggregate( [
{ $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
] )
In addition to unwinding the documents where the sizes
is an array
of elements or a non-null, non-array field, the operation outputs,
without modification, those documents where the sizes
field is
missing, null or an empty array:
{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 2, "item" : "EFG" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }
{ "_id" : 4, "item" : "LMN" }
{ "_id" : 5, "item" : "XYZ", "sizes" : null }