No MongoDB, o
$mergeObjects
operador de pipeline de agregação combina vários documentos em um único documento. Sintaxe
Os
$mergeObjects
O operador suporta duas sintaxes. Sintaxe 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Sintaxe 2:
{ $mergeObjects: <document> }
A primeira sintaxe aceita vários argumentos e a segunda sintaxe aceita um argumento.
Exemplo de sintaxe 1 (vários argumentos)
A primeira sintaxe envolve fornecer
$mergeObjects
com mais de um argumento/documento. $mergeObjects
em seguida, combina esses documentos em um. Suponha que tenhamos uma coleção chamada
users
com o seguinte documento:{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
Podemos usar
$mergeObjects
para mesclar o name
e contact
Campos:db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Resultado:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson", "email" : "[email protected]", "ph" : null } }
Nesse caso, mesclamos os dois campos em um único campo chamado
user
. Se tivéssemos mais campos/documentos, poderíamos fundi-los também, se quiséssemos. Nomes de campo duplicados
Se os documentos a serem mesclados contiverem nomes de campo duplicados,
$mergeObjects
substitui o campo à medida que mescla os documentos. Portanto, o campo no documento resultante contém o valor do último documento mesclado para esse campo. Suponha que temos o seguinte documento:
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
Podemos ver que ambos os documentos contêm um campo chamado
f_name
. Veja o que acontece quando mesclamos esses documentos:
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Resultado:
{ "_id" : 2, "user" : { "f_name" : "Bart", "l_name" : "Griffin", "email" : "[email protected]" } }
O
f_name
campo no documento resultante contém Bart
, que é o valor do último documento que foi mesclado. Valores nulos
Se estiver mesclando um documento com
null
, o documento resultante será devolvido sem alterações. Mas se todos os documentos a serem mesclados forem
null
, um documento vazio é retornado. Suponha que temos os seguintes documentos:
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Veja o que acontece quando mesclamos o
name
e contact
campos nesses dois documentos:db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
)
Resultado:
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Exemplos de sintaxe 2 (argumento único)
Aqui estão dois exemplos que usam a sintaxe de argumento único.
$group
Acumulador de Estágio
No primeiro exemplo,
$mergeObjects
é usado como um $group
acumulador de palco. Suponha que tenhamos uma coleção chamada
products
com os seguintes documentos:{ "_id" : 1, "product" : "Shirt", "inventory" : { "blue" : 10, "red" : 2 } } { "_id" : 2, "product" : "Shirt", "inventory" : { "green" : 3, "black" : 1 } } { "_id" : 3, "product" : "Shorts", "inventory" : { "blue" : 2, "red" : 8 } } { "_id" : 4, "product" : "Shorts", "inventory" : { "green" : 5, "black" : 3 } }
Podemos agrupar esses documentos por seu
product
campo e, em seguida, use $mergeObjects
para mesclar o inventory
campo para cada grupo:db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty()
Resultado:
{ "_id" : "Shorts", "mergedProducts" : { "blue" : 2, "red" : 8, "green" : 5, "black" : 3 } } { "_id" : "Shirt", "mergedProducts" : { "blue" : 10, "red" : 2, "green" : 3, "black" : 1 } }
Matrizes
Este exemplo se aplica a
$mergeObjects
para um único documento que contém um campo com uma matriz de documentos. Suponha que tenhamos uma coleção chamada
test
com os seguintes documentos:{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
Podemos aplicar
$mergeObjects
para os data
campo:db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Resultado:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Campos ausentes
$mergeObjects
ignora quaisquer campos ausentes. Ou seja, se você fornecer um campo que não existe, ele o ignora. Se nenhum dos campos existir, ele retornará um documento vazio. Exemplo:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty()
Resultado:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson" } } { "_id" : 2, "user" : { "f_name" : "Peter", "l_name" : "Griffin" } } { "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
No entanto, veja o que acontece quando nenhum dos campos existem:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Resultado:
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
O resultado é um documento vazio.
É o mesmo ao usar a sintaxe de argumento único.
Exemplo:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Resultado:
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }