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 trongmessages
sau đó mảng:-
$map
để lặp lại vòng lặp củamessages
mảng và kiểm tra điều kiện nếufrom
tìm thấy rồi nốisubMessages
hiện tại mảng với đầu vào mớisubMessage
sử 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
messages
hiệ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 }
)