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" }