0
0
MongodbHow-ToBeginner · 4 min read

How to Use $merge in Aggregation in MongoDB

Use the $merge stage in a MongoDB aggregation pipeline to output the results into a specified collection. It can insert new documents or update existing ones based on matching fields, allowing you to combine or replace data efficiently within the database.
📐

Syntax

The $merge stage has this basic syntax inside an aggregation pipeline:

  • into: The target collection name or an object specifying the database and collection.
  • on: Field(s) to match documents between source and target for updates.
  • whenMatched: Action when a match is found (e.g., replace, merge, keepExisting, fail).
  • whenNotMatched: Action when no match is found (e.g., insert, discard, fail).
mongodb
{
  $merge: {
    into: "targetCollection",
    on: "_id",
    whenMatched: "merge",
    whenNotMatched: "insert"
  }
}
💻

Example

This example shows how to aggregate documents from orders collection and merge the results into summary collection, updating existing documents by matching on _id and inserting new ones if no match exists.

mongodb
db.orders.aggregate([
  {
    $group: {
      _id: "$customerId",
      totalAmount: { $sum: "$amount" },
      orderCount: { $sum: 1 }
    }
  },
  {
    $merge: {
      into: "summary",
      on: "_id",
      whenMatched: "merge",
      whenNotMatched: "insert"
    }
  }
])
Output
Documents in 'summary' collection will be updated or inserted with aggregated totals per customerId.
⚠️

Common Pitfalls

  • Not specifying the on field causes $merge to match documents by _id by default, which may not be intended.
  • Using whenMatched: "replace" will overwrite the entire document, possibly losing fields.
  • Forgetting to handle whenNotMatched can cause errors or data loss.
  • Target collection must exist or MongoDB will create it; ensure indexes if needed.
mongodb
/* Wrong: No 'on' field, default _id matching may fail */
db.orders.aggregate([
  { $merge: { into: "summary" } }
])

/* Correct: Specify 'on' field explicitly */
db.orders.aggregate([
  { $merge: { into: "summary", on: "customerId", whenMatched: "merge", whenNotMatched: "insert" } }
])
📊

Quick Reference

OptionDescriptionExample Values
intoTarget collection or { db, coll } object"summary" or { db: "sales", coll: "summary" }
onField(s) to match documents"_id" or ["field1", "field2"]
whenMatchedAction if match found"replace", "merge", "keepExisting", "fail"
whenNotMatchedAction if no match found"insert", "discard", "fail"

Key Takeaways

Use $merge to output aggregation results into a collection, updating or inserting documents.
Always specify the 'on' field to control how documents match between source and target.
Choose 'whenMatched' and 'whenNotMatched' options carefully to avoid unwanted data loss.
MongoDB creates the target collection if it doesn't exist, but indexes must be managed separately.
$merge is powerful for combining aggregation results with existing data efficiently.