In MongoDB, il $mergeObjects
l'operatore della pipeline di aggregazione combina più documenti in un unico documento.
Sintassi
Il $mergeObjects
operatore supporta due sintassi.
Sintassi 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Sintassi 2:
{ $mergeObjects: <document> }
La prima sintassi accetta più argomenti e la seconda sintassi accetta un argomento.
Esempio di sintassi 1 (argomenti multipli)
La prima sintassi prevede di fornire $mergeObjects
con più di un argomento/documento. $mergeObjects
quindi combina quei documenti in uno solo.
Supponiamo di avere una collezione chiamata users
con il seguente documento:
{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
Possiamo usare $mergeObjects
per unire il name
e contact
campi:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Risultato:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson", "email" : "[email protected]", "ph" : null } }
In questo caso, abbiamo unito entrambi i campi in un unico campo chiamato user
. Se avessimo avuto più campi/documenti avremmo potuto unire anche quelli se lo avessimo voluto.
Nomi campi duplicati
Se i documenti da unire contengono nomi di campo duplicati, $mergeObjects
sovrascrive il campo mentre unisce i documenti. Pertanto, il campo nel documento risultante contiene il valore dell'ultimo documento unito per quel campo.
Supponiamo di avere il seguente documento:
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
Possiamo vedere che entrambi i documenti contengono un campo chiamato f_name
.
Ecco cosa succede quando uniamo quei documenti:
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Risultato:
{ "_id" : 2, "user" : { "f_name" : "Bart", "l_name" : "Griffin", "email" : "[email protected]" } }
Il f_name
il campo nel documento risultante contiene Bart
, che è il valore dell'ultimo documento unito.
Valori Nulli
Se si unisce un documento con null
, il documento risultante verrà restituito senza alcuna modifica.
Ma se tutti i documenti da unire sono null
, viene restituito un documento vuoto.
Supponiamo di avere i seguenti documenti:
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Ecco cosa succede quando uniamo il name
e contact
campi in questi due documenti:
db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
)
Risultato:
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Esempi di sintassi 2 (argomento singolo)
Di seguito sono riportati due esempi che utilizzano la sintassi dell'argomento singolo.
$group
Accumulatore di stadi
Nel primo esempio, $mergeObjects
è usato come $group
accumulatore di stadi.
Supponiamo di avere una collezione chiamata products
con i seguenti documenti:
{ "_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 } }
Possiamo raggruppare questi documenti in base al loro product
campo, quindi utilizzare $mergeObjects
per unire l'inventory
campo per ogni gruppo:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty()
Risultato:
{ "_id" : "Shorts", "mergedProducts" : { "blue" : 2, "red" : 8, "green" : 5, "black" : 3 } } { "_id" : "Shirt", "mergedProducts" : { "blue" : 10, "red" : 2, "green" : 3, "black" : 1 } }
Array
Questo esempio applica $mergeObjects
a un singolo documento che contiene un campo con una matrice di documenti.
Supponiamo di avere una collezione chiamata test
con i seguenti documenti:
{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
Possiamo applicare $mergeObjects
ai data
campo:
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Risultato:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Campi mancanti
$mergeObjects
ignora tutti i campi mancanti. Cioè, se fornisci un campo che non esiste, lo ignora. Se nessuno dei campi esiste, restituisce un documento vuoto.
Esempio:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty()
Risultato:
{ "_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" : { } }
Tuttavia, ecco cosa succede quando nessuno dei campi esistono:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Risultato:
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
Il risultato è un documento vuoto.
È lo stesso quando si utilizza la sintassi a argomento singolo.
Esempio:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Risultato:
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }