$mergeObjects (aggregation)
Definition
Combines multiple documents into a single document.
$mergeObjects is available in these stages:
Syntax
When used as a $bucket, $bucketAuto, or
$group stage accumulator, $mergeObjects has
this syntax:
{ $mergeObjects: <document> }
When used in other expressions (including in $bucket,
$bucketAuto, and $group stages) but not as an
accumulator, $mergeObjects has this syntax:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
The <document> can be any valid expression that resolves to a document.
Behavior
$mergeObjects ignores null operands. If all the
operands to $mergeObjects resolves to null,
$mergeObjects returns an empty document { }.
$mergeObjects overwrites the field values as it merges the
documents. If documents to merge include the same field name, the field,
in the resulting document, has the value from the last document merged
for the field.
Example | Results | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| | ||||||||
| | ||||||||
| | ||||||||
| |
Examples
$mergeObjects
Create a collection orders with the following documents:
db.orders.insertMany( [ { "_id" : 1, "item" : "abc", "price" : 12, "ordered" : 2 }, { "_id" : 2, "item" : "jkl", "price" : 20, "ordered" : 1 } ] )
Create another collection items with the following documents:
db.items.insertMany( [ { "_id" : 1, "item" : "abc", description: "product 1", "instock" : 120 }, { "_id" : 2, "item" : "def", description: "product 2", "instock" : 80 }, { "_id" : 3, "item" : "jkl", description: "product 3", "instock" : 60 } ] )
The following operation first uses the $lookup stage to
join the two collections by the item fields and then uses
$mergeObjects in the $replaceRoot to merge
the joined documents from items and orders:
db.orders.aggregate( [ { $lookup: { from: "items", localField: "item", // field in the orders collection foreignField: "item", // field in the items collection as: "fromItems" } }, { $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$fromItems", 0 ] }, "$$ROOT" ] } } }, { $project: { fromItems: 0 } } ] )
The operation returns the following documents:
{ _id: 1, item: 'abc', description: 'product 1', instock: 120, price: 12, ordered: 2 }, { _id: 2, item: 'jkl', description: 'product 3', instock: 60, price: 20, ordered: 1 }
$mergeObjects as an Accumulator
Create a collection sales with the following documents:
db.sales.insertMany( [ { _id: 1, year: 2017, item: "A", quantity: { "2017Q1": 500, "2017Q2": 500 } }, { _id: 2, year: 2016, item: "A", quantity: { "2016Q1": 400, "2016Q2": 300, "2016Q3": 0, "2016Q4": 0 } } , { _id: 3, year: 2017, item: "B", quantity: { "2017Q1": 300 } }, { _id: 4, year: 2016, item: "B", quantity: { "2016Q3": 100, "2016Q4": 250 } } ] )
The following operation uses $mergeObjects as a
accumulator in a $group stage that groups documents by the
item field:
Note
When used as an accumulator, $mergeObjects operator
accepts a single operand.
db.sales.aggregate( [ { $group: { _id: "$item", mergedSales: { $mergeObjects: "$quantity" } } } ] )
The operation returns the following documents:
{ _id: 'A', mergedSales: { '2017Q1': 500, '2017Q2': 500, '2016Q1': 400, '2016Q2': 300, '2016Q3': 0, '2016Q4': 0 } }, { _id: 'B', mergedSales: { '2017Q1': 300, '2016Q3': 100, '2016Q4': 250 } }
Note
If the documents to merge include the same field name, the field in the resulting document has the value from the last document merged for the field.