Viele Aktualisierungsvorgänge in MongoDB können Upserts sein. Ein Upsert ist eine Kombination aus einem Insert und einem Update.
Es funktioniert so:Sie führen einen Aktualisierungsvorgang basierend auf Filterkriterien durch, und wenn es Übereinstimmungen gibt, werden nur die übereinstimmenden Dokumente aktualisiert, aber wenn es keine Übereinstimmungen gibt, wird ein neues Dokument eingefügt.
Beispiel
Angenommen, wir haben eine Sammlung namens pets
die folgende Dokumente enthält:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Wir könnten die folgende Aktualisierungsoperation ausführen, die den upsert
setzt Parameter auf true
:
db.pets.updateOne(
{ name: "Wag" },
{ $set: { type: "Cow" } },
{ upsert: true }
)
Ergebnis:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
In diesem Fall gab es ein passendes Dokument (d. h. es gibt ein Dokument mit name: "Wag"
) und daher wurde das übereinstimmende Dokument aktualisiert. Es wurde nichts eingefügt.
Wir können dies wie folgt überprüfen:
db.pets.find()
Ergebnis:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Das erste Dokument hat jetzt einen type
von Cow
.
Lassen Sie uns einen weiteren Aktualisierungsvorgang ausführen, wieder mit upsert: true
. Aber diesmal gibt es kein passendes Dokument zum Aktualisieren.
db.pets.updateOne(
{ name: "Bubbles" },
{ $set: { type: "Fish" } },
{ upsert: true }
)
Ergebnis:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : ObjectId("5fe1b4c8d9914101694100b7") }
In diesem Beispiel versuchen wir, ein Dokument mit name: "Bubbles"
zu finden aber es ist nichts zu finden.
Dieses Mal können wir sehen, dass matchedCount
ist 0
, und der modifiedCount
ist auch 0
. Das bedeutet, dass keines der vorhandenen Dokumente aktualisiert wurde.
Wir können auch sehen, dass eine upsertedId
zurückgegeben, was bedeutet, dass ein Dokument eingefügt wurde.
Schauen wir uns noch einmal die Dokumentensammlung an:
db.pets.find()
Ergebnis:
{ "_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" }
Wir können sehen, dass ein neues Dokument eingefügt/erweitert wurde und dieselbe ID wie oben angegeben hat.
Das Upsert ist aufgetreten, weil diesmal keine übereinstimmenden Dokumente zum Aktualisieren vorhanden waren (und stattdessen ein neues eingefügt/upsertiert wurde).
Wenn wir upsert: true
nicht gesetzt hätten , wäre dieses Dokument nicht eingefügt worden.
Upsert bei Massenaktualisierungen
Wenn Sie beim Durchführen einer Massenaktualisierung upsert: true
angeben möchten , müssen Sie es mit Bulk.find.upsert()
verwenden .
Dies kann mit den folgenden Schreiboperationen verwendet werden:
Bulk.find.replaceOne()
Bulk.find.updateOne()
Bulk.find.update()
Die Syntax lautet wie folgt:
Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);
Beispiel:
var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
{
name: "Bruce",
type: "Bat",
}
);
bulk.execute();
Ergebnis:
BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("5fe1c179d9914101694100dd") } ] })
Wir können sehen, dass ein Dokument eingefügt wurde. Wir können auch die _id
sehen die für dieses Dokument generiert wurde.
Wenn wir uns jetzt die Dokumente in unserer Sammlung ansehen, können wir das neu eingefügte Dokument sehen:
db.pets.find()
Ergebnis:
{ "_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" }