Veel update-bewerkingen in MongoDB kunnen upserts zijn. Een upsert is een combinatie van een insert en een update.
Het werkt als volgt:u voert een updatebewerking uit op basis van filtercriteria en als er overeenkomsten zijn, worden alleen de overeenkomende documenten bijgewerkt, maar als er geen overeenkomsten zijn, wordt een nieuw document ingevoegd.
Voorbeeld
Stel dat we een verzameling hebben met de naam pets
die de volgende documenten bevat:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
We kunnen de volgende updatebewerking uitvoeren die de upsert
. instelt parameter naar true
:
db.pets.updateOne(
{ name: "Wag" },
{ $set: { type: "Cow" } },
{ upsert: true }
)
Resultaat:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
In dit geval was er een overeenkomend document (d.w.z. er is een document met name: "Wag"
) en daarom is het overeenkomende document bijgewerkt. Er is niets ingevoegd.
We kunnen dit als volgt verifiëren:
db.pets.find()
Resultaat:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Het eerste document heeft nu een type
van Cow
.
Laten we nog een update uitvoeren, opnieuw met upsert: true
. Maar deze keer is er geen overeenkomend document om bij te werken.
db.pets.updateOne(
{ name: "Bubbles" },
{ $set: { type: "Fish" } },
{ upsert: true }
)
Resultaat:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : ObjectId("5fe1b4c8d9914101694100b7") }
In dit voorbeeld proberen we een document te vinden met name: "Bubbles"
maar er is niets te vinden.
Deze keer kunnen we zien dat de matchedCount
is 0
, en de modifiedCount
is ook 0
. Dit betekent dat geen van de bestaande documenten is bijgewerkt.
We kunnen ook zien dat een upsertedId
is geretourneerd, wat betekent dat een document is geüpdatet.
Laten we nog eens kijken naar de verzameling documenten:
db.pets.find()
Resultaat:
{ "_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" }
We kunnen zien dat er een nieuw document is ingevoegd/geüpdatet en dat het dezelfde ID heeft als hierboven aangegeven.
De upsert vond plaats omdat er deze keer geen overeenkomende documenten waren om bij te werken (en dus in plaats daarvan een nieuwe werd ingevoegd/upsert).
Als we upsert: true
niet hadden ingesteld , zou dat document niet zijn ingevoegd.
Upsert op bulkupdates
Als u bij het uitvoeren van een bulkupdate upsert: true
. wilt specificeren , je moet het gebruiken met Bulk.find.upsert()
.
Dit kan worden gebruikt met de volgende schrijfbewerkingen:
Bulk.find.replaceOne()
Bulk.find.updateOne()
Bulk.find.update()
De syntaxis gaat als volgt:
Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);
Voorbeeld:
var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
{
name: "Bruce",
type: "Bat",
}
);
bulk.execute();
Resultaat:
BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("5fe1c179d9914101694100dd") } ] })
We kunnen zien dat één document is aangeslagen. We kunnen ook de _id
. zien die voor dat document is gegenereerd.
Als we nu de documenten in onze collectie bekijken, kunnen we het nieuwe document zien dat up-to-date was:
db.pets.find()
Resultaat:
{ "_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" }