Puoi effettivamente risolvere il tuo problema con l'aggiornamento metodo, ma devi farlo in un modo diverso se stai usando MongoDB 4.2 o successivo. Il secondo parametro può essere $set
operazione che si desidera eseguire o una aggregation
tubatura. Usando il successivo hai più libertà nel modellare i dati. Questo è il modo in cui puoi risolvere il tuo problema, analizzerò dopo:
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,
});
Innanzitutto usa l'aggiornamento metodo che passa tre parametri:
- Richiesta filtro
- Condotto di aggregazione
- Opzioni. Qui ho appena usato
new: true
per restituire il documento aggiornato e facilitarne il test.
Questa è la struttura:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
All'interno della pipeline abbiamo solo bisogno di uno stadio, il $set
per sostituire la proprietà advanced
con un array creeremo.
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
Per prima cosa mappiamo l'advanced
array per poter mappare l'array di carte nidificate dopo:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
Usiamo la variabile che abbiamo dichiarato sulla prima mappa e che contiene l'elemento corrente dell'array avanzato che viene mappato ( adv
) per accedere e mappare l'array "cards" annidato ( $$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",
}
}
}
}
}
]
...
Infine controlliamo se l'ID della carta corrente è uguale all'id cercato $eq: [ "$$advcard.id", "main-2-1" ]
e restituire la nuova carta se corrisponde o la carta corrente:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
Ecco un esempio funzionante di quanto descritto:https://mongoplayground.net/p/xivZGNeD8ng