$unwind
$unwind flattens an array into separate documents - one per element, each carrying a copy of the parent fields. Once you can picture that output, the rest of aggregation over arrays follows.
Input:
{
_id: 1,
userId: 101,
items: [
{
product: "Laptop",
price: 1000,
quantity: 1
},
{
product: "Mouse",
price: 50,
quantity: 2
}
]
}
Pipeline:
{
$unwind: "$items"
}
Output:
{
_id: 1,
userId: 101,
items: {
product: "Laptop",
price: 1000,
quantity: 1
}
}
AND:
{
_id: 1,
userId: 101,
items: {
product: "Mouse",
price: 50,
quantity: 2
}
}
One document became two documents.
This is the key idea:
Before $unwind
Order
├── Laptop
└── Mouse
After $unwind
Order + Laptop
Order + Mouse
Try it
Order 1 in the sample data has four items:
db.orders.aggregate([
{ $match: { _id: 1 } },
{ $unwind: "$items" }
])
Four documents came out, each carrying the same _id, userId and status - and one item. Change the _id and the number of output documents follows the array length.