$mergeObjects (aggregation)
Definition
New in version 3.6.
Combines multiple documents into a single document.
- When used as a
$group
stage accumulator,$mergeObjects
has the following form:
- { $mergeObjects: <document> }
- When used in other expressions, including in the
$group
stage but not as an accumulator:
- { $mergeObjects: [ <document1>, <document2>, ... ] }
The <document>
can be any valid expression that resolves to a document.
Behavior
mergeObjects
ignoresnull
operands. If all theoperands tomergeObjects
resolves to null,mergeObjects
returns an empty document{ }
.mergeObjects
overwrites the field values as it mergesthe documents. If documents to merge include the same field name, thefield, in the resulting document, has the value from the lastdocument merged for the field.
Example | Results |
---|---|
|
|
|
|
|
|
|
|
Examples
$mergeObjects
Create a collection orders
with the following documents:
- db.orders.insert([
- { "_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.insert([
- { "_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 tojoin the two collections by the item
fields and then uses$mergeObjects
in the $replaceRoot
to mergethe 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.insert( [
- { _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 aaccumulator in a $group
stage that groups documents by theitem
field:
Note
When used as an accumulator, $mergeObjects
operatoraccepts a single operand.
- db.sales.aggregate( [
- { $group: { _id: "$item", mergedSales: { $mergeObjects: "$quantity" } } }
- ])
The operation returns the following documents:
- { "_id" : "B", "mergedSales" : { "2017Q1" : 300, "2016Q3" : 100, "2016Q4" : 250 } }
- { "_id" : "A", "mergedSales" : { "2017Q1" : 500, "2017Q2" : 500, "2016Q1" : 400, "2016Q2" : 300, "2016Q3" : 0, "2016Q4" : 0 } }
Note
If the documents to merge include the same field name, the field inthe resulting document has the value from the last document mergedfor the field.