7. Expanding Arrays with $unwind

$unwind expands an array so each element produces a separate pipeline document. If an order contains three items, unwinding items produces three documents for that order.

By default, documents with null, missing, or empty arrays do not produce output from $unwind. Use preserveNullAndEmptyArrays: true to retain the parent document in those cases. includeArrayIndex can capture an element's position.

Unwinding can multiply the number of documents processed. Use it when downstream stages need individual array elements; use $map, $filter, or $reduce when the calculation can remain inside the parent document.

Unwind before grouping by an array element

For product-level summaries from embedded order items, unwind the array and then group by product identifier.

Code Example
db.orders.aggregate([
  { $match: { status: "delivered" } },
  { $unwind: "$items" },
  {
    $project: {
      orderId: "$_id",
      customerId: 1,
      productId: "$items.productId",
      productName: "$items.name",
      quantity: "$items.quantity",
      unitPrice: "$items.price",
      lineRevenue: { $multiply: ["$items.quantity", "$items.price"] }
    }
  }
]);
Key Takeaways
  • $unwind emits one document per array element.
  • Parent fields are repeated.
  • Empty arrays are dropped by default.
  • Unwinding can increase processing cost.
Knowledge Check

How many documents does a normal $unwind produce for an array with four elements?