Dans MongoDB, les $mergeObjects
l'opérateur de pipeline d'agrégation combine plusieurs documents en un seul document.
Syntaxe
Les $mergeObjects
L'opérateur prend en charge deux syntaxes.
Syntaxe 1 :
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Syntaxe 2 :
{ $mergeObjects: <document> }
La première syntaxe accepte plusieurs arguments et la seconde syntaxe accepte un argument.
Exemple de syntaxe 1 (arguments multiples)
La première syntaxe consiste à fournir $mergeObjects
avec plus d'un argument/document. $mergeObjects
combine ensuite ces documents en un seul.
Supposons que nous ayons une collection appelée users
avec le document suivant :
{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
Nous pouvons utiliser $mergeObjects
pour fusionner le name
et contact
champs :
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Résultat :
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson", "email" : "[email protected]", "ph" : null } }
Dans ce cas, nous avons fusionné les deux champs en un seul champ appelé user
. Si nous avions plus de champs/documents, nous aurions pu les fusionner aussi si nous le voulions.
Noms de champs en double
Si les documents à fusionner contiennent des noms de champs en double, $mergeObjects
écrase le champ lors de la fusion des documents. Par conséquent, le champ du document résultant contient la valeur du dernier document fusionné pour ce champ.
Supposons que nous ayons le document suivant :
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
Nous pouvons voir que les deux documents contiennent un champ nommé f_name
.
Voici ce qui se passe lorsque nous fusionnons ces documents :
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Résultat :
{ "_id" : 2, "user" : { "f_name" : "Bart", "l_name" : "Griffin", "email" : "[email protected]" } }
Le f_name
champ dans le document résultant contient Bart
, qui est la valeur du dernier document qui a été fusionné.
Valeurs nulles
Si vous fusionnez un document avec null
, le document résultant sera renvoyé sans aucune modification.
Mais si tous les documents à fusionner sont null
, un document vide est renvoyé.
Supposons que nous ayons les documents suivants :
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Voici ce qui se passe lorsque nous fusionnons le name
et contact
champs dans ces deux documents :
db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
)
Résultat :
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Exemples de syntaxe 2 (argument unique)
Voici deux exemples qui utilisent la syntaxe à argument unique.
$group
Accumulateur d'étape
Dans le premier exemple, $mergeObjects
est utilisé comme un $group
accumulateur d'étage.
Supposons que nous ayons une collection appelée products
avec les documents suivants :
{ "_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 } }
Nous pouvons regrouper ces documents par leur product
champ, puis utilisez $mergeObjects
pour fusionner l'inventory
champ pour chaque groupe :
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty()
Résultat :
{ "_id" : "Shorts", "mergedProducts" : { "blue" : 2, "red" : 8, "green" : 5, "black" : 3 } } { "_id" : "Shirt", "mergedProducts" : { "blue" : 10, "red" : 2, "green" : 3, "black" : 1 } }
Tableaux
Cet exemple applique $mergeObjects
à un seul document qui contient un champ avec un tableau de documents.
Supposons que nous ayons une collection appelée test
avec les documents suivants :
{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
Nous pouvons appliquer $mergeObjects
aux data
champ :
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Résultat :
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Champs manquants
$mergeObjects
ignore les champs manquants. Autrement dit, si vous fournissez un champ qui n'existe pas, il l'ignore. Si aucun des champs n'existe, il renvoie un document vide.
Exemple :
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty()
Résultat :
{ "_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" : { } }
Cependant, voici ce qui se passe lorsque aucun des champs existent :
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Résultat :
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
Le résultat est un document vide.
C'est la même chose lorsque vous utilisez la syntaxe à argument unique.
Exemple :
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Résultat :
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }