Wiele operacji aktualizacji w MongoDB może potencjalnie być upsertami. Upsert to połączenie wkładki i aktualizacji.
Działa to tak:wykonujesz operację aktualizacji w oparciu o kryteria filtrowania, a jeśli są jakieś dopasowania, aktualizowane są tylko dopasowane dokumenty, ale jeśli nie ma dopasowań, wstawiany jest nowy dokument.
Przykład
Załóżmy, że mamy kolekcję o nazwie pets
który zawiera następujące dokumenty:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Moglibyśmy wykonać następującą operację aktualizacji, która ustawia upsert
parametr na true
:
db.pets.updateOne(
{ name: "Wag" },
{ $set: { type: "Cow" } },
{ upsert: true }
)
Wynik:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
W tym przypadku był pasujący dokument (tzn. istnieje dokument z name: "Wag"
), w związku z czym zaktualizowano odpowiedni dokument. Nic nie zostało wstawione.
Możemy to zweryfikować w następujący sposób:
db.pets.find()
Wynik:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Pierwszy dokument ma teraz type
Cow
.
Uruchommy kolejną operację aktualizacji, ponownie używając upsert: true
. Ale tym razem nie będzie pasującego dokumentu do aktualizacji.
db.pets.updateOne(
{ name: "Bubbles" },
{ $set: { type: "Fish" } },
{ upsert: true }
)
Wynik:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : ObjectId("5fe1b4c8d9914101694100b7") }
W tym przykładzie próbujemy znaleźć dokument, który ma name: "Bubbles"
ale nic nie można znaleźć.
Tym razem widzimy, że matchedCount
to 0
i modifiedCount
to także 0
. Oznacza to, że żaden z istniejących dokumentów nie został zaktualizowany.
Widzimy również, że upsertedId
został zwrócony, co oznacza, że dokument został zamieniony.
Przyjrzyjmy się jeszcze raz kolekcji dokumentów:
db.pets.find()
Wynik:
{ "_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" }
Widzimy, że nowy dokument został wstawiony/zamieniony i ma taki sam identyfikator, jak wskazano powyżej.
Upsert wystąpił, ponieważ tym razem nie było pasujących dokumentów do aktualizacji (a więc zamiast tego został wstawiony/zamieniony nowy).
Gdybyśmy nie ustawili upsert: true
, ten dokument nie zostałby wstawiony.
Zwróć uwagę na aktualizacje zbiorcze
Podczas wykonywania zbiorczej aktualizacji, jeśli chcesz określić upsert: true
, musisz go użyć z Bulk.find.upsert()
.
Może być używany z następującymi operacjami zapisu:
Bulk.find.replaceOne()
Bulk.find.updateOne()
Bulk.find.update()
Składnia wygląda tak:
Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);
Przykład:
var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
{
name: "Bruce",
type: "Bat",
}
);
bulk.execute();
Wynik:
BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("5fe1c179d9914101694100dd") } ] })
Widzimy, że jeden dokument został sfałszowany. Możemy również zobaczyć _id
który został wygenerowany dla tego dokumentu.
Teraz, gdy przeglądamy dokumenty w naszej kolekcji, możemy zobaczyć nowy dokument, który został wstawiony:
db.pets.find()
Wynik:
{ "_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" }