Nhiều hoạt động cập nhật trong MongoDB có khả năng bị cảnh báo. Bản nâng cấp là sự kết hợp giữa phần chèn và bản cập nhật.
Nó hoạt động như thế này:Bạn thực hiện thao tác cập nhật dựa trên tiêu chí bộ lọc và nếu có bất kỳ kết quả phù hợp nào, chỉ những tài liệu phù hợp mới được cập nhật, nhưng nếu không có tài liệu phù hợp nào thì một tài liệu mới sẽ được chèn vào.
Ví dụ
Giả sử chúng ta có một bộ sưu tập có tên là pets
chứa các tài liệu sau:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Chúng tôi có thể thực hiện thao tác cập nhật sau để đặt upsert
tham số thành true
:
db.pets.updateOne(
{ name: "Wag" },
{ $set: { type: "Cow" } },
{ upsert: true }
)
Kết quả:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
Trong trường hợp này, có một tài liệu phù hợp (tức là có một tài liệu có name: "Wag"
) và do đó tài liệu phù hợp đã được cập nhật. Không có gì được chèn.
Chúng tôi có thể xác minh điều này như sau:
db.pets.find()
Kết quả:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Tài liệu đầu tiên hiện có type
của Cow
.
Hãy chạy một thao tác cập nhật khác, một lần nữa bằng cách sử dụng upsert: true
. Nhưng lần này, sẽ không có tài liệu phù hợp để cập nhật.
db.pets.updateOne(
{ name: "Bubbles" },
{ $set: { type: "Fish" } },
{ upsert: true }
)
Kết quả:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : ObjectId("5fe1b4c8d9914101694100b7") }
Trong ví dụ này, chúng tôi cố gắng tìm một tài liệu có name: "Bubbles"
nhưng không có cái nào được tìm thấy.
Lần này, chúng ta có thể thấy rằng matchedCount
là 0
và modifiedCount
cũng là 0
. Điều này có nghĩa là không có tài liệu hiện có nào được cập nhật.
Chúng ta cũng có thể thấy rằng một upsertedId
đã được trả lại, có nghĩa là một tài liệu đã được nâng cấp.
Hãy cùng nhìn lại bộ sưu tập tài liệu:
db.pets.find()
Kết quả:
{ "_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" }
Chúng ta có thể thấy rằng một tài liệu mới đã được chèn / nâng cấp và nó có cùng một ID như được chỉ ra ở trên.
Việc nâng cấp xảy ra do lần này không có tài liệu phù hợp để cập nhật (và do đó, một tài liệu mới đã được chèn / nâng cấp thay thế).
Nếu chúng tôi chưa đặt upsert: true
, tài liệu đó sẽ không được chèn vào.
Cập nhật hàng loạt bản cập nhật
Khi thực hiện cập nhật hàng loạt, nếu bạn muốn chỉ định upsert: true
, bạn cần sử dụng nó với Bulk.find.upsert()
.
Điều này có thể được sử dụng với các hoạt động ghi sau:
-
Bulk.find.replaceOne()
-
Bulk.find.updateOne()
-
Bulk.find.update()
Cú pháp như sau:
Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);
Ví dụ:
var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
{
name: "Bruce",
type: "Bat",
}
);
bulk.execute();
Kết quả:
BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("5fe1c179d9914101694100dd") } ] })
Chúng ta có thể thấy rằng một tài liệu đã được nâng cấp. Chúng ta cũng có thể thấy _id
đã được tạo cho tài liệu đó.
Bây giờ khi chúng tôi xem các tài liệu trong bộ sưu tập của mình, chúng tôi có thể thấy tài liệu mới đã được nâng cấp:
db.pets.find()
Kết quả:
{ "_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" }