Definición
$Utilice el posicional
$operador para identificar un elemento en una matriz para actualizar sin especificar explícitamente la posición del elemento en la matriz.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>].
Compatibilidad
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.
Sintaxis
El operador posicional $ tiene la forma:
{ "<array>.$" : value }
Cuando se utilizan operaciones de actualización, como db.collection.updateOne() y, deben cumplirse ambas condiciones db.collection.findAndModify() siguientes:
El operador posicional
$actúa como un marcador de posición para el primer elemento que coincide conquery document.El
arraycampo debe aparecer como partequery documentdel.
Por ejemplo:
db.collection.updateOne( { <array>: value ... }, { <update operator>: { "<array>.$" : value } } )
Comportamiento
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.
inserció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.
Arreglos anidados
No se puede utilizar el operador posicional $ para consultas que recorren más de una matriz, como consultas que recorren matrices anidadas dentro de otras matrices, porque el reemplazo del marcador $ de posición es un valor único.
No establecidos
Cuando usas el operador posicional $ con el operador $unset, el operador posicional no remueve el elemento coincidente del arreglo. En su lugar, lo establece en el elemento null.
Negaciones
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.
Puede utilizar el operador posicional si la parte negada de la consulta está dentro de una $elemMatch expresión.
Coincidencias de arreglos múltiples
El $ operador de actualización posicional se comporta de manera ambigua cuando se filtra en múltiples campos de matriz.
Cuando el servidor ejecuta un método de actualización, primero ejecuta una consulta para determinar qué documentos actualizar. Si la actualización filtra documentos en varios campos $ de la matriz, es posible que el operador de actualización posicional no actualice la posición correcta en la matriz.
Para obtener más información, consulta el ejemplo.
Ejemplos
Actualizar valores en un arreglo
Crea la 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:
db.students.insertMany ( [ { _id : 1, "grades" : [ 85, 82, 80 ] }, { _id : 2, "grades" : [ 88, 90, 92 ] }, { _id : 3, "grades" : [ 85, 100, 90 ] } ] )
Se pueden actualizar documentos en un arreglo
El operador posicional $ permite actualizar matrices con documentos incrustados. Utilice el operador posicional $ para acceder a los campos de los documentos incrustados. Utilice la notación de punto 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:
db.students.insertOne( [ { _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 } ] }
Se pueden actualizar los documentos incrustados mediante múltiples coincidencias de campo
Utilice el operador para actualizar el primer elemento de la matriz $ $elemMatch que coincida con múltiples criterios de consulta especificados con el operador.
Se puede considerar el siguiente documento de la colección students cuyo valor de campo grades es un arreglo de documentos incrustados:
db.students.insertOne( [ { _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 std campo en el primer documento incrustado que tiene un grade campo con un valor menor o igual a 90 y un mean campo con un valor mayor 80 que:
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 } ] }
Se puede actualizar con coincidencias de múltiples arreglos
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. El ejemplo filtra los documentos usando los campos activity_ids, deans_list y grades, y actualiza el valor 2021 del 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 updateOne método anterior, filtra los documentos disponibles utilizando los valores de los campos de la matriz proporcionados. Aunque el deans_list campo se utiliza en el filtro, no es el campo que utiliza el operador de actualización posicional $ para determinar qué posición de la matriz actualizar:
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 realizar coincidencias en múltiples matrices, utilice el operador posicional $[<identifier>] filtrado.
Obtén más información
Para ejemplos que utilizan el operador $ para actualizar arreglos, consulta Actualizar elementos de arreglo en un documento con operadores posicionales de MQL.