$unwind
The `$unwind` stage in the aggregation framework is used to deconstruct an array field from the input documents to output a document for each element. This is particularly useful for normalizing data stored in arrays and for performing operations on each element separately.
Syntax
{
$unwind: {
path: <field path>,
includeArrayIndex: <string>,
preserveNullAndEmptyArrays: <boolean>
}
}
Parameters
path
stringrequiredThe field path to an array field. This is a required parameter.
includeArrayIndex
stringOptional. The name of a new field to hold the array index of the unwound element.
preserveNullAndEmptyArrays
stringOptional. If true, if the path is null, missing, or an empty array, $unwind outputs the document unchanged.
Examples
Sample Data
{
"_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4",
"name": "First Up Consultants | Beverage Shop",
"sales": {
"salesByCategory": [
{ "categoryName": "Wine Accessories", "totalSales": 34440 },
{ "categoryName": "Bitters", "totalSales": 39496 }
]
}
}
Unwind sales by category
Deconstruct the salesByCategory array in the store document.
This query creates one document for each element in the salesByCategory array.
Query:
db.stores.aggregate([
{
$unwind: "$sales.salesByCategory"
}
])
Output:
[
{
"_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
"store": {
"name": "Downtown Store",
"sales": {
"totalSales": 15000,
"salesByCategory": { "category": "Electronics", "totalSales": 5000 }
}
}
}
]
Unwind promotion events with array index
Deconstruct the promotionEvents array and include the array index in the output.
This query uses includeArrayIndex to track the position of each event.
Query:
db.stores.aggregate([
{
$unwind: {
path: "$promotionEvents",
includeArrayIndex: "eventIndex"
}
}
])
Output:
[
{
"_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
"store": {
"name": "Downtown Store",
"promotionEvents": { "eventName": "Summer Sale" },
"eventIndex": 0
}
}
]