Всъщност можете да решите проблема си с актуализацията метод, но трябва да го направите по различен начин, ако използвате MongoDB 4.2 или по-нова версия. Вторият параметър може да бъде $set
операция, която искате да изпълните, или aggregation
тръбопровод. Използвайки по-късно, имате повече свобода при оформяне на данните. Това е начинът, по който можете да разрешите проблема си, ще разбия след:
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,
});
Първо използвайте актуализацията метод, предаващ три параметъра:
- Филтриране на заявка
- Тръбопровод за агрегиране
- Опции. Тук току-що използвах
new: true
за да върнете актуализирания документ и да улесните тестването му.
Това е структурата:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
Вътре в тръбопровода се нуждаем само от един етап, $set
за да замените свойството advanced
с масив, който ще създадем.
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
Първо картографираме advanced
масив, за да можете да картографирате масива с вложени карти след:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
Използваме променливата, която декларирахме на първата карта и която съдържа текущия елемент от разширения масив, който се картографира ( adv
), за достъп и картографиране на вложения масив „карти“ ( $$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",
}
}
}
}
}
]
...
Накрая проверяваме дали текущият идентификатор на картата е равен на търсения идентификатор $eq: [ "$$advcard.id", "main-2-1" ]
и върнете новата карта, ако съвпада, или текущата карта:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
Ето работещ пример за описаното:https://mongoplayground.net/p/xivZGNeD8ng