Du kan faktiskt lösa ditt problem med uppdateringen metod, men du måste göra det på ett annat sätt om du använder MongoDB 4.2 eller senare. Den andra parametern kan vara $set
operation du vill utföra eller en aggregation
rörledning. Om du använder det senare har du större frihet att forma data. Så här kan du lösa ditt problem, jag kommer att dela upp efter:
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,
});
Använd först uppdateringen metod som skickar tre parametrar:
- Filterfråga
- Aggregationspipeline
- Alternativ. Här använde jag precis
new: true
för att returnera det uppdaterade dokumentet och göra det lättare att testa.
Detta är strukturen:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
Inuti pipelinen behöver vi bara ett steg, $set
för att ersätta egenskapen advanced
med en array som vi kommer att skapa.
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
Vi mappar först den advanced
array för att kunna mappa den kapslade korten array efter:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
Vi använder variabeln som vi deklarerade på den första kartan och som innehåller den avancerade arrayen som nuvarande objekt som mappas ( adv
) för att komma åt och mappa den kapslade "kort"-arrayen ( $$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",
}
}
}
}
}
]
...
Till sist kontrollerar vi om det aktuella kort-id:t är lika med det id som söks $eq: [ "$$advcard.id", "main-2-1" ]
och returnera det nya kortet om det matchar eller det aktuella kortet:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
Här är ett fungerande exempel på vad som beskrivs:https://mongoplayground.net/p/xivZGNeD8ng