Docs Menu
Docs Home
/ /
Arreglos

$ (operador de actualización)

$

El operador posicional $ identifica un elemento en un arreglo para actualizar sin especificar explícitamente la posición del elemento en el arreglo.

Nota

Desambiguación

  • Para proyectar o devolver un elemento de matriz desde una operación de lectura, consulte la $ operador de proyección en su lugar.

  • Para actualizar todos los elementos en un arreglo, se puede consultar en cambio el operador posicional all $[].

  • Para actualizar todos los elementos que coincidan con una condición o condiciones de filtro de arreglo, se puede consultar en cambio el operador posicional filtrado $[<identifier>].

Se puede usar el operador posicional $ para implementaciones alojadas en los siguientes entornos:

  • MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube

  • MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB

  • MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.

El operador posicional $ tiene la forma:

{ "<array>.$" : value }

Cuando se utiliza con operaciones de actualización, por ejemplo db.collection.updateOne() y db.collection.findAndModify(),

  • el operador posicional $ actúa como marcador de posición del primer elemento que coincida con query document, y

  • el campo array debe aparecer como parte de query document.

Por ejemplo:

db.collection.updateOne(
{ <array>: value ... },
{ <update operator>: { "<array>.$" : value } }
)

A partir de MongoDB 5.0, los operadores de actualización procesan los campos de documentos con nombres basados en cadenas en orden lexicográfico. Los campos con nombres numéricos se procesan en orden numérico. Consulta Comportamiento del operador de actualización para obtener más información.

No se debe utilizar el operador $ en operaciones de actualización o inserción. Si la query de actualización no coincide con ningún documento existente, la inserción falla porque el operador $ necesita un elemento de arreglo coincidente.

El operador posicional $ no puede utilizarse para aquellas query que atraviesan más de un arreglo, como las query que atraviesan arreglos anidados dentro de otros arreglos, debido a que el reemplazo para el marcador de posición $ es un valor único

Cuando se usa con el operador $unset, el operador posicional $ no elimina el elemento coincidente del arreglo, sino que lo establece en null.

Si la query coincide con el arreglo utilizando un operador de negación, como $ne, $not, o $nin, entonces no se puede utilizar el operador posicional para actualizar los valores de este arreglo.

Sin embargo, si la parte negada de la query está dentro de una expresión $elemMatch, entonces se puede utilizar el operador posicional para actualizar este campo.

El operador de actualización posicional $ se comporta de forma ambigua en el filtrado de varios campos de arreglo.

Cuando el servidor ejecuta un método de actualización, primero ejecuta una query para determinar qué documentos quieres actualizar. Si la actualización filtra documentos en varios campos del arreglo, la llamada posterior al operador de actualización posicional $ no siempre actualiza la posición requerida en el arreglo.

Para obtener más información, consulta el ejemplo.

Cree una colección students con los siguientes documentos:

db.students.insertMany( [
{ "_id" : 1, "grades" : [ 85, 80, 80 ] },
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
] )

Para actualizar el primer elemento cuyo valor es 80 a 82 en el arreglo grades, utiliza el operador posicional $ si no conoces la posición del elemento en el arreglo:

Importante

Se debe incluir el campo de arreglo como parte del documento query.

db.students.updateOne(
{ _id: 1, grades: 80 },
{ $set: { "grades.$" : 82 } }
)

El operador posicional $ actúa como un marcador de posición para la primera coincidencia del documento de query a actualizar.

Después de la operación, la colección students contiene los siguientes documentos:

{ "_id" : 1, "grades" : [ 85, 82, 80 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }

El operador posicional $ facilita las actualizaciones de arreglos que contienen documentos incrustados. Utiliza el operador posicional $ para acceder a los campos en los documentos incrustados con la notación de puntos en el operador $.

db.collection.updateOne(
{ <query selector> },
{ <update operator>: { "array.$.field" : value } }
)

Se puede considerar el siguiente documento en la colección students cuyo valor del elemento grades es un arreglo de documentos incrustados:

{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 85, std: 8 }
]
}

Utiliza el operador posicional $ para actualizar el campo std del primer elemento del arreglo que coincida con la condición grade igual a 85:

Importante

Se debe incluir el campo de arreglo como parte del documento query.

db.students.updateOne(
{ _id: 4, "grades.grade": 85 },
{ $set: { "grades.$.std" : 6 } }
)

Después de la operación, el documento tiene los siguientes valores actualizados:

{
"_id" : 4,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 8 },
{ "grade" : 85, "mean" : 90, "std" : 6 },
{ "grade" : 85, "mean" : 85, "std" : 8 }
]
}

El operador $ puede actualizar el primer elemento del arreglo que coincida con varios criterios de query especificados con el operador $elemMatch.

Se puede considerar el siguiente documento de la colección students cuyo valor de campo grades es un arreglo de documentos incrustados:

{
_id: 5,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 90, mean: 85, std: 3 }
]
}

En el siguiente ejemplo, el operador $ actualiza el valor del campo std en el primer documento incrustado que tiene el campo grade con un valor menor o igual a 90 y un campo mean con un valor mayor que 80:

db.students.updateOne(
{
_id: 5,
grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
},
{ $set: { "grades.$.std" : 6 } }
)

Esta operación actualiza el primer documento incrustado que cumple con los criterios, es decir, el segundo documento incrustado en el arreglo:

{
_id: 5,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 6 },
{ grade: 90, mean: 85, std: 3 }
]
}

El operador posicional de actualización $ se comporta de forma ambigua cuando la query tiene varios campos de arreglo para filtrar los documentos de la colección.

Se puede considerar un documento en la colección students_deans_list, que contiene arreglos de información de estudiantes:

db.students_deans_list.insertMany( [
{
_id: 8,
activity_ids: [ 1, 2 ],
grades: [ 90, 95 ],
deans_list: [ 2021, 2020 ]
}
] )

En el siguiente ejemplo, el usuario intenta modificar el campo deans_list, aplicando un filtro a los documentos utilizando los campos activity_ids, deans_list y grades y para actualizar el valor de 2021 en el campo deans_list a 2022:

db.students_deans_list.updateOne(
{ activity_ids: 1, grades: 95, deans_list: 2021 },
{ $set: { "deans_list.$": 2022 } }
)

Cuando el servidor ejecuta el método updateOne mencionado anteriormente, filtra los documentos disponibles usando los valores de los campos del arreglo proporcionados. Aunque el campo deans_list se utiliza en el filtro, no es el campo que utiliza el operador de actualización posicional $ para determinar la posición del arreglo que debe actualizarse:

db.students_deans_list.find( { _id: 8 } )

Ejemplo de salida:

{
_id: 8,
activity_ids: [ 1, 2 ],
grades: [ 90, 95 ],
deans_list: [ 2021, 2022 ]
}

El método updateOne coincidió con el campo deans_list en 2021, pero el operador de actualización posicional $ cambió el valor 2020 a 2022.

Para evitar resultados inesperados al hacer coincidir varios arreglos, se debe usar en cambio el operador posicional filtrado $[<identifier>].

Tip

Para ejemplos que utilizan el operador $ para actualizar arreglos, consulta Actualizar elementos de arreglo en un documento con operadores posicionales de MQL.

Volver

Arreglos

En esta página