U kunt uw probleem daadwerkelijk oplossen met de update methode, maar u moet het op een andere manier doen als u MongoDB 4.2 of hoger gebruikt. De tweede parameter kan de $set
. zijn bewerking die u wilt uitvoeren of een aggregation
pijpleiding. Als u de laatste gebruikt, heeft u meer vrijheid bij het vormgeven van de gegevens. Dit is de manier waarop u uw probleem kunt oplossen, ik zal het oplossen na:
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,
});
Gebruik eerst de update methode die drie parameters doorgeeft:
- Zoekopdracht filteren
- Aggregatiepijplijn
- Opties. Hier heb ik zojuist
new: true
. gebruikt om het bijgewerkte document terug te sturen en het testen gemakkelijker te maken.
Dit is de structuur:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
Binnen de pijplijn hebben we maar één fase nodig, de $set
om de eigenschap advanced
te vervangen met een array die we zullen maken.
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
We brengen eerst de advanced
. in kaart array om de array van geneste kaarten te kunnen toewijzen na:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
We gebruiken de variabele die we op de eerste kaart hebben gedeclareerd en die het geavanceerde array-item bevat dat wordt toegewezen ( adv
) om de geneste "kaarten"-array te openen en toe te wijzen ( $$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",
}
}
}
}
}
]
...
Ten slotte controleren we of het huidige kaart-ID gelijk is aan het ID waarnaar wordt gezocht $eq: [ "$$advcard.id", "main-2-1" ]
en retourneer de nieuwe kaart als deze overeenkomt of de huidige kaart:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
Hier is een werkend voorbeeld van wat wordt beschreven:https://mongoplayground.net/p/xivZGNeD8ng