De nombreuses opérations de mise à jour dans MongoDB peuvent être des upserts. Un upsert est une combinaison d'un insert et d'une mise à jour.
Cela fonctionne comme ceci :vous effectuez une opération de mise à jour basée sur des critères de filtre, et s'il y a des correspondances, seuls les documents correspondants sont mis à jour, mais s'il n'y a pas de correspondances, un nouveau document est inséré.
Exemple
Supposons que nous ayons une collection appelée pets qui contient les documents suivants :
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }
Nous pourrions effectuer l'opération de mise à jour suivante qui définit le upsert paramètre à true :
db.pets.updateOne(
{ name: "Wag" },
{ $set: { type: "Cow" } },
{ upsert: true }
) Résultat :
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
Dans ce cas, il y avait un document correspondant (c'est-à-dire qu'il y a un document avec name: "Wag" ) et par conséquent le document correspondant a été mis à jour. Rien n'a été inséré.
Nous pouvons le vérifier comme suit :
db.pets.find() Résultat :
{ "_id" : 1, "name" : "Wag", "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }
Le premier document a maintenant un type de Cow .
Exécutons une autre opération de mise à jour, en utilisant à nouveau upsert: true . Mais cette fois, il n'y aura pas de document correspondant à mettre à jour.
db.pets.updateOne(
{ name: "Bubbles" },
{ $set: { type: "Fish" } },
{ upsert: true }
) Résultat :
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("5fe1b4c8d9914101694100b7")
}
Dans cet exemple, nous essayons de trouver un document qui a name: "Bubbles" mais il n'y en a pas à trouver.
Cette fois, nous pouvons voir que le matchedCount est 0 , et le modifiedCount vaut aussi 0 . Cela signifie qu'aucun des documents existants n'a été mis à jour.
Nous pouvons également voir qu'un upsertedId a été renvoyé, ce qui signifie qu'un document a été mis à jour.
Reprenons la collection de documents :
db.pets.find() Résultat :
{ "_id" : 1, "name" : "Wag", "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }
{ "_id" : ObjectId("5fe1b4c8d9914101694100b7"), "name" : "Bubbles", "type" : "Fish" } Nous pouvons voir qu'un nouveau document a été inséré/mis à jour et qu'il a le même ID que celui indiqué ci-dessus.
L'upsert s'est produit parce que cette fois il n'y avait pas de documents correspondants à mettre à jour (et donc un nouveau a été inséré/mis à jour à la place).
Si nous n'avions pas défini upsert: true , ce document n'aurait pas été inséré.
Upsert sur les mises à jour groupées
Lors d'une mise à jour groupée, si vous souhaitez spécifier upsert: true , vous devez l'utiliser avec Bulk.find.upsert() .
Cela peut être utilisé avec les opérations d'écriture suivantes :
Bulk.find.replaceOne()Bulk.find.updateOne()Bulk.find.update()
La syntaxe ressemble à ceci :
Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>); Exemple :
var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
{
name: "Bruce",
type: "Bat",
}
);
bulk.execute(); Résultat :
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 1,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [
{
"index" : 0,
"_id" : ObjectId("5fe1c179d9914101694100dd")
}
]
})
Nous pouvons voir qu'un document a été modifié. Nous pouvons également voir le _id qui a été généré pour ce document.
Désormais, lorsque nous visualisons les documents de notre collection, nous pouvons voir le nouveau document qui a été mis à jour :
db.pets.find() Résultat :
{ "_id" : 1, "name" : "Wag", "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }
{ "_id" : ObjectId("5fe1b4c8d9914101694100b7"), "name" : "Bubbles", "type" : "Fish" }
{ "_id" : ObjectId("5fe1c179d9914101694100dd"), "name" : "Bruce", "type" : "Bat" }