23. Writing Aggregation Results with $out and $merge

$out and $merge persist aggregation results to a collection. $out is useful for replacing a report collection when its semantics fit the task. $merge offers configurable behavior for matching and nonmatching target documents.

Design refresh behavior carefully. A $merge does not necessarily remove old report documents that are absent from the new output. Decide on match keys, whenMatched, whenNotMatched, stale-record cleanup, permissions, and recovery procedures before deploying a write pipeline.

A merge is not necessarily a full refresh

Old summary documents that are absent from the current pipeline output may remain in the target collection. Plan stale-data cleanup explicitly.

Code Example
db.orders.aggregate([
  { $match: { status: "delivered" } },
  { $unwind: "$items" },
  {
    $group: {
      _id: "$items.productId",
      productName: { $first: "$items.name" },
      unitsSold: { $sum: "$items.quantity" },
      revenue: { $sum: { $multiply: ["$items.quantity", "$items.price"] } }
    }
  },
  {
    $merge: {
      into: "productRevenueReport",
      on: "_id",
      whenMatched: "replace",
      whenNotMatched: "insert"
    }
  }
]);
Key Takeaways
  • $out and $merge persist results.
  • $merge supports matched and unmatched behaviors.
  • Plan for stale records and repeated execution.
  • Test write pipelines and permissions carefully.
Knowledge Check

What can happen when using $merge to refresh a summary report?