The $mergeObjects accumulator folds many sub-documents in each $group bucket into one combined object—perfect for rolling up quarterly metrics, profile patches, or nested maps without manual field copying.
01
One object per group
Merge nested fields.
02
Single operand
Accumulator syntax.
03
Last wins
Duplicate keys overwrite.
04
Null ignored
Skips null documents.
05
vs expression form
Array merge elsewhere.
06
vs $setUnion
Objects vs arrays.
Fundamentals
Definition and Usage
$mergeObjects is a MongoDB operator that combines document fields into a single embedded document. Used as an accumulator inside $group, it evaluates one document expression on every row in the group and merges all resulting objects together.
💡
Beginner tip
Think of it like spreading objects together in JavaScript: { ...obj1, ...obj2, ...obj3 }. Each grouped document contributes its object; fields with the same name keep the last value seen.
Common uses include merging quarterly sales maps per product, combining user preference patches, or flattening nested metadata after grouping. When you need to merge two specific documents in a non-group stage, use the expression form with an array: { $mergeObjects: [ docA, docB ] }.
Foundation
📝 Syntax
As a $group accumulator, $mergeObjects takes one document expression:
Array of document expressions merged left to right. Used outside accumulator context—e.g. in $replaceRoot after a join.
$mergeObjects: [
"$a", "$b"
]
overwrite behaviorBehavior
When two sources define the same key, the later source wins. Order within a group follows MongoDB’s internal processing—not guaranteed unless you $sort first.
// last doc sets status
null handlingEdge case
Null operands are dropped. Missing fields evaluate to null and are skipped. An all-null group returns { }.
// null → ignored
Hands-On
Examples Gallery
Sales records with nested quantity maps—merge quarterly figures per product, explore overwrite rules, and combine collections with the expression form.
📚 Getting Started
Sample sales data and the core $mergeObjects grouping pattern from the MongoDB docs.
Every document for item A contributes its quantity keys. Because quarter names differ across years, keys accumulate without collision—one object holds the full history.
📈 Practical Patterns
Profile patches, overwrite behavior, and joining collections with the expression form.
Example 3 — Merge profile patches per user
Users receive partial profile updates stored as sub-documents. Merge them into one profile per user:
Each patch adds new keys to the merged object. This pattern replaces manual $push + post-processing when you only need the final combined settings object.
Example 4 — Duplicate keys: last document wins
When two documents in the same group share a field name, the later value overwrites the earlier one:
This uses the expression form (array syntax), not the accumulator. Item fields merge first; $$ROOT order fields overwrite on name clashes—here _id and item come from the order.
Compare
📋 $mergeObjects vs related operators
Operator
Input
Returns
Best for
$mergeObjects (accumulator)
One object per document
Single merged object
Roll up nested maps in $group
$mergeObjects (expression)
Array of documents
Single merged object
Join flattening, defaults + overrides
$push
Any value
Array of all values
Keep every object separately
$setUnion
Arrays
Unique array elements
Distinct tag lists
$replaceRoot + manual fields
Explicit projection
Custom shape
When you need rename/remap logic
🧠 How $mergeObjects Works
1
Documents bucketed
$group assigns each document to a bucket via _id.
Group
2
Object extracted
The operand expression (e.g. "$quantity") is evaluated per document; null results are skipped.
Evaluate
3
Fields combined
MongoDB merges all objects in the group. New keys are added; duplicate keys keep the last value.
Merge
=
📦
One object returned
A single embedded document per group containing all merged fields—or { } if nothing valid was found.
Important
📝 Notes
Accumulator form accepts one document expression; expression form accepts an array of documents.
Duplicate field names keep the value from the last merged document—use $sort when order matters.
Null operands are ignored; an all-null group returns an empty object { }.
Operands must resolve to objects, not scalars or bare arrays.
Also available as accumulator in $bucket and $bucketAuto stages.
$mergeObjects is the go-to accumulator when grouped documents each carry a partial object and you need one combined result—quarterly metrics, config patches, or metadata maps.
Remember the two syntax shapes: single operand in $group, array operand elsewhere. When keys collide, the last document wins—sort first if that order is business-critical. Next up: $min for finding minimum values per group.
Use unique key names inside nested maps (e.g. "2017Q1") to avoid accidental overwrites
Add $sort before $group when last-wins order must be deterministic
Filter null patches in $match to keep merged objects clean
Use expression form with $lookup + $replaceRoot to flatten joined documents
Validate merged output shape with $project before writing to downstream collections
❌ Don’t
Pass an array operand inside $group—accumulator form needs a single expression
Expect deep recursive merge—only top-level fields are merged (nested objects replace wholesale)
Confuse $mergeObjects with $setUnion (objects vs array deduplication)
Merge scalar fields directly—wrap them in an object or use a different accumulator
Assume document processing order within a group without an explicit $sort
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about $mergeObjects
Use these points when folding nested objects inside $group.
5
Core concepts
📦01
Merge objects
One doc per group.
Basics
📄02
Single operand
In $group context.
Syntax
🔄03
Last wins
Duplicate keys.
Behavior
🚫04
Null skipped
Empty → { }.
Edge case
🔗05
Array form
For $lookup joins.
Pattern
❓ Frequently Asked Questions
$mergeObjects combines multiple sub-documents from documents in the same $group bucket into one embedded document. Each document contributes its object fields; the result is a single merged object per group.
Inside $group (and also $bucket / $bucketAuto): { merged: { $mergeObjects: "$profile" } }. The operand must be a single expression that resolves to a document—not an array of documents.
As an accumulator: { $mergeObjects: <one document expression> }. As a general expression: { $mergeObjects: [ doc1, doc2, ... ] }. The array form merges a fixed list of documents in order; the accumulator form merges one object per grouped document.
Later values overwrite earlier ones. If three documents in a group all have a status field, the merged object keeps the value from the last document MongoDB processes for that field.
No. Null operands are ignored. If every document in a group resolves to null, $mergeObjects returns an empty object { }.
$mergeObjects merges object fields into one document. $setUnion works on arrays and returns unique array elements. Use $mergeObjects for nested maps like quarterly sales quantities; use $setUnion for tag lists.
Did you know?
$mergeObjects performs a shallow merge—nested objects are replaced as a whole, not merged field-by-field at every depth. For deep merging you need custom logic or multiple pipeline stages. See the official $mergeObjects docs.