Bạn thực sự có thể giải quyết vấn đề của mình bằng cập nhật nhưng bạn phải thực hiện theo một cách khác nếu bạn đang sử dụng MongoDB 4.2 trở lên. Tham số thứ hai có thể là $set
thao tác bạn muốn thực hiện hoặc aggregation
đường ống dẫn. Sử dụng càng về sau, bạn càng có nhiều quyền tự do trong việc định hình dữ liệu. Đây là cách bạn có thể giải quyết vấn đề của mình, tôi sẽ phân tích sau:
db.collection.update({
"cards.advanced.unit": 2
},
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
cards: {
$map: {
input: "$$adv.cards",
as: "advcard",
in: {
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard.id"
},
"$$advcard"
]
}
}
},
unit: "$$adv.unit"
}
}
}
}
}
],
{
new: true,
});
Đầu tiên với việc sử dụng cập nhật phương thức truyền ba tham số:
- Lọc truy vấn
- Quy trình tổng hợp
- Các tùy chọn. Ở đây tôi vừa sử dụng
new: true
để trả lại tài liệu đã cập nhật và giúp kiểm tra dễ dàng hơn.
Đây là cấu trúc:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
Bên trong đường dẫn, chúng ta chỉ cần một giai đoạn, $set
để thay thế thuộc tính advanced
với một mảng mà chúng tôi sẽ tạo.
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
Đầu tiên, chúng tôi ánh xạ advanced
mảng để có thể ánh xạ mảng thẻ lồng nhau sau:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
Chúng tôi sử dụng biến mà chúng tôi đã khai báo trên bản đồ đầu tiên và có chứa mục hiện tại của mảng nâng cao đang được ánh xạ (adv
) để truy cập và ánh xạ mảng "thẻ" lồng nhau ($$adv.cards
):
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
cards: {
$map: {
input: "$$adv.cards",
as: "advcard",
in: {
// We place our condition to check for the chosen card here
}
}
},
unit: "$$adv.unit",
}
}
}
}
}
]
...
Cuối cùng, chúng tôi kiểm tra xem id thẻ hiện tại có bằng với id đang được tìm kiếm không $eq: [ "$$advcard.id", "main-2-1" ]
và trả lại thẻ mới nếu nó khớp hoặc thẻ hiện tại:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
Dưới đây là ví dụ hoạt động về những gì được mô tả: https://mongoplayground.net/p/xivZGNeD8ng