De hecho, puede resolver su problema con la actualización método, pero debe hacerlo de una manera diferente si está utilizando MongoDB 4.2 o posterior. El segundo parámetro puede ser el $set
operación que desea realizar o una aggregation
tubería. Usando el último, tiene más libertad para dar forma a los datos. Esta es la forma en que puede resolver su problema, lo desglosaré después:
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,
});
Primero con el uso de la actualización método que pasa tres parámetros:
- Consulta de filtro
- Canalización de agregación
- Opciones. Aquí solo usé
new: true
para devolver el documento actualizado y facilitar la prueba.
Esta es la estructura:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
Dentro de la canalización solo necesitamos una etapa, el $set
para reemplazar la propiedad advanced
con una matriz que crearemos.
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
Primero mapeamos el advanced
matriz para poder mapear la matriz de tarjetas anidadas después de:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
Usamos la variable que declaramos en el primer mapa y que contiene el elemento actual de la matriz avanzada que se está mapeando ( adv
) para acceder y mapear la matriz de "tarjetas" anidadas ( $$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",
}
}
}
}
}
]
...
Por último, verificamos si la identificación de la tarjeta actual es igual a la identificación que se busca $eq: [ "$$advcard.id", "main-2-1" ]
y devolver la nueva tarjeta si coincide o la tarjeta actual:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
Aquí hay un ejemplo práctico de lo que se describe:https://mongoplayground.net/p/xivZGNeD8ng