Tôi e rằng không thể thực hiện được với một bản cập nhật nguyên tử, bạn sẽ phải thực hiện một vài thao tác cập nhật thỏa mãn cả hai điều kiện.
Chia logic cập nhật thành hai thao tác cập nhật riêng biệt, thao tác đầu tiên sẽ yêu cầu sử dụng vị trí $
nhà điều hành
để xác định phần tử trong history
mảng bạn muốn và mã $ set >
để cập nhật các trường hiện có. Thao tác này tuân theo logic cập nhật trường NẾU tên VÀ tổ chức khớp
Bây giờ, bạn muốn sử dụng findAndModify ()
cho thao tác này vì nó có thể trả về tài liệu đã cập nhật. Theo mặc định, tài liệu trả về không bao gồm các sửa đổi được thực hiện trên bản cập nhật.
Vì vậy, trang bị kho vũ khí này, sau đó bạn có thể thăm dò logic thứ hai của mình trong thao tác tiếp theo, tức là cập nhật NẾU sự kết hợp của "history.name" và "history.organisation" không tồn tại trong mảng . Với thao tác cập nhật thứ hai này, sau đó bạn cần sử dụng $ push
toán tử để thêm các phần tử.
Ví dụ sau đây thể hiện khái niệm trên. Ban đầu nó giả định rằng bạn có phần truy vấn và tài liệu được cập nhật dưới dạng các đối tượng riêng biệt.
Ví dụ:khi chúng tôi có tài liệu khớp với mảng lịch sử hiện có, nó sẽ chỉ thực hiện một thao tác cập nhật duy nhất, nhưng nếu tài liệu không khớp thì findAndModify ()
phương thức sẽ trả về null, sử dụng logic này trong thao tác cập nhật thứ hai của bạn để đẩy tài liệu vào mảng:
var doc = {
"name": "Test123",
"organisation": "Rat"
}, // document to update. Note: the doc here matches the existing array
query = { "email": "[email protected]" }; // query document
query["history.name"] = doc.name; // create the update query
query["history.organisation"] = doc.organisation;
var update = db.users.findAndModify({
"query": query,
"update": {
"$set": {
"history.$.name": doc.name,
"history.$.organisation": doc.organisation
}
}
}); // return the document modified, if there's no matched document update = null
if (!update) {
db.users.update(
{ "email": query.email },
{ "$push": { "history": doc } }
);
}
Sau thao tác này đối với các tài liệu phù hợp, việc truy vấn bộ sưu tập sẽ mang lại kết quả tương tự
db.users.find({ "email": "[email protected]" });
Đầu ra:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
}
]
}
Bây giờ hãy xem xét các tài liệu không khớp:
var doc = {
"name": "foo",
"organisation": "bar"
}, // document to update. Note: the doc here does not matches the current array
query = { "email": "[email protected]" }; // query document
query["history.name"] = doc.name; // create the update query
query["history.organisation"] = doc.organisation;
var update = db.users.findAndModify({
"query": query,
"update": {
"$set": {
"history.$.name": doc.name,
"history.$.organisation": doc.organisation
}
}
}); // return the document modified, if there's no matched document update = null
if (!update) {
db.users.update(
{ "email": query.email },
{ "$push": { "history": doc } }
);
}
Truy vấn bộ sưu tập này cho tài liệu này
db.users.find({ "email": "[email protected]" });
sẽ mang lại
Đầu ra:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
},
{
"name" : "foo",
"organisation" : "bar"
}
]
}