Trong MongoDB, db.collection.findAndModify()
phương thức sửa đổi và trả về một tài liệu.
Bộ sưu tập collection
một phần là tên của tập hợp để thực hiện thao tác với nó.
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 ta có thể sử dụng db.collection.findAndModify()
phương pháp để sửa đổi một trong những tài liệu đó.
db.pets.findAndModify({
query: { type: "Dog" },
update: { type: "Cow" }
})
Kết quả:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
Theo mặc định, nó trả về tài liệu gốc (không phải phiên bản đã sửa đổi).
Lưu ý rằng chỉ có một con chó được cập nhật, mặc dù có hai con chó trong bộ sưu tập.
Hãy kiểm tra bộ sưu tập.
db.pets.find()
Kết quả:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Chúng ta có thể thấy rằng tài liệu đầu tiên hiện có chứa một con bò thay vì một con chó. Tuy nhiên, chúng tôi cũng có thể thấy rằng trường tên của tài liệu đã biến mất.
Đó là bởi vì, khi bạn chuyển một tài liệu vào update
đối số, db.collection.findAndModify()
thực hiện thay thế.
Sử dụng Toán tử cập nhật
Nếu chúng tôi muốn cập nhật một trường, nhưng giữ nguyên phần còn lại của tài liệu, chúng tôi sẽ cần bao gồm / các biểu thức toán tử cập nhật có liên quan trong tài liệu của mình.
Với bộ sưu tập ở trạng thái hiện tại, hãy thực hiện một findAndModify()
khác hoạt động chống lại nó, nhưng lần này chúng tôi sẽ sử dụng $set
cập nhật toán tử để chỉ đặt trường chúng tôi muốn thay đổi.
db.pets.findAndModify({
query: { type: "Dog" },
update: { $set: { type: "Horse" } }
})
Kết quả:
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
Lần này con chó còn lại đã được cập nhật.
Hãy xem bộ sưu tập.
db.pets.find()
Kết quả:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Lần này trường liên quan đã được cập nhật và phần còn lại của tài liệu vẫn còn nguyên vẹn.
Trả lại tài liệu đã sửa đổi
Theo mặc định, tài liệu gốc được trả về khi bạn sử dụng db.collection.findAndModify()
.
Thay vào đó, nếu bạn muốn trả lại tài liệu đã sửa đổi, hãy sử dụng new
tham số.
Theo mặc định, đây là new: false
, dẫn đến tài liệu gốc được trả lại. Nhưng chỉ định new: true
thay vào đó, tài liệu đã sửa đổi sẽ được trả lại.
Hãy thực hiện một sửa đổi khác, nhưng lần này chúng ta sẽ sử dụng new: true
.
db.pets.findAndModify({
query: { name: "Meow" },
update: { $set: { name: "Scratch" } },
new: true
})
Kết quả:
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Vì vậy, chúng tôi đã đổi tên Meow
thành Scratch
và đầu ra phản ánh những thay đổi của chúng tôi.
Cảnh báo phía trên
Bạn có thể thực hiện các cảnh báo bằng cách chỉ định upsert: true
.
Nâng cấp là một tùy chọn mà bạn có thể sử dụng trên các hoạt động cập nhật. Nếu tài liệu đã chỉ định không tồn tại, một tài liệu mới sẽ được chèn vào. Nếu nó không tồn tại, sau đó tài liệu gốc được cập nhật (và không có tài liệu nào được chèn vào).
Ví dụ sử dụng upsert: false
Dưới đây là một ví dụ về việc cố gắng cập nhật một tài liệu không tồn tại khi upsert: false
.
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true
})
Kết quả:
null
Tài liệu không tồn tại trong bộ sưu tập và vì vậy findAndModify()
trả về null
. Mặc dù chúng tôi không chỉ định upsert: false
, chúng tôi biết điều đó là sai vì đó là giá trị mặc định (tức là giá trị được sử dụng khi bạn không chỉ định tùy chọn nâng cấp).
Nếu chúng ta xem xét lại bộ sưu tập, chúng ta có thể thấy rằng tài liệu không được nâng cấp.
db.pets.find()
Kết quả:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Ví dụ sử dụng upsert: true
Bây giờ nó lại ở đây, nhưng lần này chúng tôi chỉ định upsert: true
.
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true,
upsert: true
})
Kết quả:
{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }
Lần này, một tài liệu mới được nâng cấp và chúng tôi thấy tài liệu được nâng cấp là đầu ra (vì chúng tôi đã chỉ định new: true
).
Hãy kiểm tra lại bộ sưu tập.
db.pets.find()
Kết quả:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" } { "_id" : 4, "name" : "Fetch", "type" : "Dog" }
Vì vậy, chúng ta có thể thấy rằng tài liệu mới trên thực tế đã được nâng cấp.
Tham số bộ lọc mảng
Khi làm việc với mảng, bạn có thể sử dụng arrayFilters
cùng với tham số $
vị trí toán tử để xác định phần tử mảng nào cần cập nhật. Điều này cho phép bạn cập nhật một phần tử mảng dựa trên giá trị của nó, ngay cả khi bạn không biết vị trí của nó.
Ví dụ:giả sử chúng ta có một bộ sưu tập có tên là players
với các tài liệu sau:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
Chúng tôi có thể chạy truy vấn sau để chỉ cập nhật những phần tử mảng có giá trị cao hơn một số lượng nhất định (trong trường hợp này là 10).
db.players.findAndModify({
query: { scores: { $gte: 10 } },
update: { $set: { "scores.$[e]" : 10 } },
arrayFilters: [ { "e": { $gte: 10 } } ]
})
Kết quả:
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
Như mong đợi, điều này chỉ cập nhật một tài liệu, mặc dù hai tài liệu phù hợp với tiêu chí.
Đây là giao diện của các tài liệu bây giờ.
db.players.find()
Kết quả:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 10, 10 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
Tài liệu 2 đã cập nhật hai phần tử mảng, vì những phần tử đó phù hợp với tiêu chí.
Thông tin thêm
db.collection.findAndModify()
phương thức cũng chấp nhận các tham số khác, chẳng hạn như writeConcern
, collation
, bypassDocumentValidation
và hơn thế nữa.
Xem tài liệu MongoDB cho db.collections.findAndModify()
để biết thêm thông tin.