Menu Docs

$mergeObjects (aggregation)

$mergeObjects

Combina vários documentos em um único documento.

$mergeObjects está disponível nesses estágios:

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 expressão that resolves to a document.

$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.

Exemplo
Resultados
{ $mergeObjects: [ { a: 1 }, null ] }
{ a: 1 }
{ $mergeObjects: [ null, null ] }
{ }
{
$mergeObjects: [
{ a: 1 },
{ a: 2, b: 2 },
{ a: 3, c: 3 }
]
}
{ a: 3, b: 2, c: 3 }
{
$mergeObjects: [
{ a: 1 },
{ a: 2, b: 2 },
{ a: 3, b: null, c: 3 }
]
}
{ a: 3, b: null, c: 3 }

Crie uma collection orders com os seguintes documentos:

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 } }
] )

A operação retorna os seguintes documentos:

{
_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
}

Crie uma collection sales com os seguintes documentos:

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:

Observação

When used as an accumulator, $mergeObjects operator accepts a single operand.

db.sales.aggregate( [
{ $group: { _id: "$item", mergedSales: { $mergeObjects: "$quantity" } } }
] )

A operação retorna os seguintes documentos:

{
_id: 'A',
mergedSales: { '2017Q1': 500, '2017Q2': 500, '2016Q1': 400, '2016Q2': 300, '2016Q3': 0, '2016Q4': 0 }
},
{
_id: 'B',
mergedSales: { '2017Q1': 300, '2016Q3': 100, '2016Q4': 250 }
}

Observação

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.