Nâng cấp sẽ không hoạt động trong các tài liệu lồng nhau trong truy vấn cập nhật,
Bạn có thể thử cập nhật phức tạp với truy vấn tổng hợp để xử lý các trường hợp của mình nếu bạn muốn thực hiện nó trong một truy vấn duy nhất,
Hãy lấy ví dụ đầu vào và xem ví dụ về trường hợp khôn ngoan,
Trường hợp 1: Nếu được chỉ định messages.from trường tồn tại trong messages mảng
var to = "111";
var from = "222";
var subMessage = {
message: "test",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Trường hợp 2: Nếu messages.from trường không tồn tại trong mảng
var to = "111";
var from = "333";
var subMessage = {
message: "test2",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Trường hợp 3: Nếu tài liệu không tồn tại
var to = "111";
var from = "333";
var subMessage = {
message: "test2",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Truy vấn cuối cùng của bạn sẽ là,
- chỉ kiểm tra
tođiều kiện trong truy vấn - cập nhật một phần, kiểm tra tình trạng,
- if
fromđược tìm thấy trongmessagessau đó mảng:-
$mapđể lặp lại vòng lặp củamessagesmảng và kiểm tra điều kiện nếufromtìm thấy rồi nốisubMessageshiện tại mảng với đầu vào mớisubMessagesử dụng$concatArrays,$mergeObjectsđể hợp nhất đối tượng hiện tại với đối tượng đã cập nhật
-
- khác từ không tìm thấy sau đó nối mảng đối tượng thư mới trong
messageshiện tại mảng sử dụng$cocnatArrays
- if
-
upsert: true, để chèn tài liệu mới nếu không tìm thấy trong bộ sưu tập
db.pendingMessages.updateOne(
{ to: to },
[{
$set: {
messages: {
$cond: [
{ $in: [from, { $ifNull: ["$messages.from", []] }] },
{
$map: {
input: "$messages",
in: {
$mergeObjects: [
"$$this",
{
subMessages: {
$cond: [
{ $eq: ["$$this.from", from] },
{
$concatArrays: ["$$this.subMessages", [subMessage]]
},
"$$this.subMessages"
]
}
}
]
}
}
},
{
$concatArrays: [
{ $ifNull: ["$messages", []] },
[
{
from: from,
subMessages: [subMessage]
}
]
]
}
]
}
}
}],
{ upsert: true }
)