MongoDB con controladores
Esta página documenta una mongosh . Para ver el método equivalente en un driver de MongoDB, se debe consultar la página correspondiente al lenguaje de programación:
Definición
Compatibilidad
Este método está disponible en implementaciones alojadas en los siguientes entornos:
MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube
Nota
Este comando es compatible con todos los clústeres de MongoDB Atlas. Para obtener información sobre el soporte de Atlas para todos los comandos, consulte Comandos no compatibles.
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 método updateMany() tiene la siguiente forma:
db.collection.updateMany( <filter>, <update>, { upsert: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ], hint: <document|string>, let: <document>, maxTimeMS: <int>, bypassDocumentValidation: <boolean> } )
Parámetros
El método updateMany() toma los siguientes parámetros:
Parameter | Tipo | Descripción | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Documento | Los criterios de selección para actualizar. Los mismos selectores query que en el método Especifica un documento vacío | |||||||||||||||||||
documento o pipeline | Las modificaciones que se deben aplicar puede ser una de las siguientes:
Para actualizar con un documento de reemplazo, consulta | |||||||||||||||||||
| booleano | Opcional. Cuando
Para evitar múltiples inserciones, asegúrate de que los campos de Se establece por defecto en | ||||||||||||||||||
| Documento | Opcional. Un documento que expresa el nivel de confirmación de escritura. Omite el uso del nivel de confirmación de escritura por defecto. No establezcas explícitamente el nivel de confirmación de escritura para la operación si se ejecuta en una transacción. Para usar el nivel de confirmación de escritura con transacciones, consulta Transacciones y nivel de confirmación de escritura. | ||||||||||||||||||
| Documento | Opcional. Especifica la intercalación a utilizar para la operación. La intercalación permite a los usuarios especificar reglas propias del lenguaje para la comparación de strings, como reglas para el uso de mayúsculas y minúsculas y marcas de acento. La opción de intercalación tiene la siguiente sintaxis: Al especificar la intercalación, el campo Si no se especifica la intercalación, pero la colección tiene una intercalación por defecto (ver Si no se especifica ninguna intercalación para la colección o para las operaciones, MongoDB utiliza la comparación binaria simple usada en versiones anteriores para las comparaciones de strings. No puedes especificar varias intercalaciones para una operación. Por ejemplo, no puedes especificar diferentes intercalaciones por campo, o si realizas una búsqueda con un ordenamiento, no puedes usar una intercalación para la búsqueda y otra para el ordenamiento. | ||||||||||||||||||
| arreglo | Opcional. Un arreglo de documentos de filtro que determinan qué elementos del arreglo modificar para una operación de actualización en un campo de arreglo. En el documento de actualización, usa el operador posicional filtrado El Puedes incluir el mismo identificador varias veces en el documento de actualización; sin embargo, para cada identificador distinto ( Sin embargo, se pueden especificar condiciones compuestas sobre el mismo identificador en un único documento de filtro, como en los siguientes ejemplos: Para obtener ejemplos, consulta Especificar | ||||||||||||||||||
Documento o string | Opcional. Un documento o string que especifica el índice que se utilizará para respaldar el predicado de query. La opción puede tomar un documento de especificación de índice o la string de nombre de índice. Si especifica un índice que no existe, la operación genera un error. Para un ejemplo, consulta Especificar | |||||||||||||||||||
Documento | Opcional. Especifica un documento que contiene una lista de variables. Esto le permite mejorar la legibilidad de los comandos al separar las variables del texto de la query. La sintaxis del documento es: La variable se establece en el valor devuelto por la expresión y no puede modificarse posteriormente. Para acceder al valor de una variable en el comando, se debe usar el prefijo de doble signo de dólar ( Para usar una variable para los resultados del filtro, debes acceder a la variable dentro del operador Para un ejemplo completo usando | |||||||||||||||||||
entero | Opcional. Especifica el límite de tiempo en milisegundos para que la operación de actualización se ejecute antes de que se agote el tiempo de espera. | |||||||||||||||||||
booleano | Opcional. Permite que |
Devuelve
El método devuelve un documento que contiene:
Un valor booleano
acknowledgedentruesi la operación se ejecutó con nivel de confirmación de escritura (write concern) o enfalsesi el nivel de confirmación de escritura (write concern) estaba deshabilitadomatchedCountque contiene el número de documentos coincidentesmodifiedCountque contiene el número de documentos modificadosupsertedIdque contiene el_idpara el documento actualizado o insertadoupsertedCountque contiene la cantidad de documentos actualizados o insertados
Control de acceso
En las implementaciones que se ejecutan con authorization, el usuario debe tener acceso que incluya los siguientes privilegios:
updateacción en las colecciones especificadas.findacción en las colecciones especificadas.insertacción en las colecciones especificadas si la operación produce una inserción.
El rol con funcionalidad incorporada readWrite proporciona los privilegios necesarios.
Comportamiento
updateMany() encuentra todos los documentos en la colección que coinciden con filter y aplica las modificaciones especificadas por el parámetro update.
updateMany() modifica cada documento individualmente. Cada operación de guardar documento es una operación atómica, pero updateMany() en su conjunto no es atómica. Si su caso de uso requiere la atomicidad de las escrituras en varios documentos, utilice Transacciones.
Si falla la actualización de un solo documento, se conservan todas las actualizaciones de documentos escritas antes del fallo, pero los documentos restantes que coinciden no se actualizan. Para obtener más detalles sobre este comportamiento, consulta Fallos en las actualizaciones múltiples.
Tip
Colecciones fragmentadas para obtener más información sobre el comportamiento de updateMany() en las colecciones fragmentadas.
Limitaciones
updateMany()debería usarse solo para operaciones idempotentes.
Inserción
Si upsert: true y ningún documento coincide con el filter, db.collection.updateMany() crea un nuevo documento basado en los parámetros filter y update.
Si especificas upsert: true en una colección fragmentada, debe incluir la clave de partición completa en la filter. Para obtener información sobre el comportamiento adicional de db.collection.updateMany(), consulta Colecciones fragmentadas.
Actualiza con un documento de actualización de expresiones de operador
Para la especificación de modificación, el método db.collection.updateMany() puede aceptar un documento que solo contiene expresiones de Operadores de actualización para ejecutar.
Por ejemplo:
db.collection.updateMany( <query>, { $set: { status: "D" }, $inc: { quantity: 2 } }, ... )
Actualiza con un pipeline de agregación
El método db.collection.updateMany() puede aceptar una pipeline de agregación [ <stage1>, <stage2>, ... ] que especifica las modificaciones a realizar. La pipeline puede constar de las siguientes etapas:
$addFieldsy su alias$set$replaceRooty su alias$replaceWith
El uso de un pipeline de agregación permite una instrucción de actualización más expresiva, como expresar actualizaciones condicionales basadas en los valores actuales de los campos o actualizar un campo con el valor de otros campos.
Por ejemplo:
db.collection.updateMany( <query>, [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } }, { $unset: [ "misc1", "misc2" ] } ] ... )
Nota
En esta pipeline, $set y $unset son etapas de agregación, a diferencia de los operadores de actualización. Las etapas de agregación $set y $unset añaden nuevos campos a los documentos y no modifican los valores de los campos existentes.
Para obtener más información sobre los operadores de actualización, consulta $set y $unset.
Para ver ejemplos, consulta Actualización con pipeline de agregación.
Colecciones con tamaño fijo
Si una operación de actualización cambia el tamaño del documento, la operación fallará.
Colecciones de series de tiempo
El método updateMany() está disponible para colecciones de series de tiempo a partir de MongoDB 5.1.
Los comandos de actualización deben cumplir con los siguientes requisitos:
Solo puedes hacer coincidir el valor del campo
metaField.Solo puedes modificar el valor del campo
metaField.El documento de actualización solo puede contener expresiones de operador de actualización.
Su comando para actualizar no debe limitar el número de documentos que se deben actualizar. Establezca
multi: trueo utilice el métodoupdateMany().El comando de actualización no debe establecer inserción: true.
Colecciones fragmentadas
updateMany() presenta los siguientes comportamientos cuando se utiliza con colecciones fragmentadas:
updateMany()las operaciones que incluyenupsert: truedeben incluir la clave de fragmentación completa en elfilter.Si intentas ejecutar
updateMany()durante una migración de rangos o una actualización de valores de la clave de partición, la operación puede omitir documentos en algunos casos. Para asegurarte de que todos los documentos estén actualizados, utiliza actualizaciones idempotentes y vuelve a ejecutar el comando hasta que no se apliquen más actualizaciones. Para obtener más información sobre las actualizaciones idempotentes conupdateMany(), consulta Actualizaciones idempotentes.
Si
updateMany()se ejecuta fuera de una transacción, las operaciones que apuntan a más de una partición difunden la operación a todas las particiones del clúster.Si
updateMany()se ejecuta dentro de una transacción, las operaciones que apuntan a más de una partición solo afectan a las particiones relevantes.
Explicabilidad
updateMany() no es compatible con db.collection.explain().
Transacciones
db.collection.updateMany() puede usarse dentro de transacciones distribuidas.
Importante
En la mayoría de los casos, una transacción distribuida incurre en un costo de rendimiento mayor que las escrituras de documentos individuales, y la disponibilidad de transacciones distribuidas no debería ser un sustituto para un diseño de esquema efectivo. Para muchos casos, el modelo de datos desnormalizado (documento incrustado y matrices) seguirá siendo óptimo para tus datos y casos de uso. Es decir, en muchos casos, modelar tus datos de forma adecuada minimizará la necesidad de transacciones distribuidas.
Para consideraciones adicionales sobre el uso de transacciones (como el límite de tiempo de ejecución y el límite de tamaño del oplog), consulta también las consideraciones de producción.
Inserta dentro de transacciones
Puede crear colecciones e índices dentro de una transacción distribuida si la transacción es No es una transacción de escritura entre fragmentos.
db.collection.updateMany() con upsert: true puede ejecutarse en una colección existente o en una colección inexistente. Si se ejecuta en una colección que es inexistente, la operación crea la colección.
Nivel de confirmación de escritura y transacciones
No establezcas explícitamente el nivel de confirmación de escritura para la operación si se ejecuta en una transacción. Para usar el nivel de confirmación de escritura con transacciones, consulta Transacciones y nivel de confirmación de escritura.
Entradas de OpLog
updateMany() añade una entrada al oplog (registro de operaciones) por cada documento actualizado con éxito. Si no se actualizan documentos, updateMany() no añade entradas al oplog.
Ejemplos
Idempotent Updates
El siguiente ejemplo demuestra una actualización idempotente con updateMany():
Una empresa está otorgando un aumento de $1,000 a todos los empleados que ganan menos de $100,000.
Considere una colección employees con los siguientes documentos:
db.employees.insertMany( [ { _id: 1, name: "Rob", salary: 37000 }, { _id: 2, name: "Trish", salary: 65000 }, { _id: 3, name: "Zeke", salary: 99999 }, { _id: 4, name: "Mary", salary: 200000 } ] )
El siguiente comando coincide con todos los empleados que ganan menos de $100,000 y no han recibido un aumento, incrementa esos salarios en $1,000 y establece raiseApplied como verdadero:
db.employees.updateMany( { salary: { $lt: 100000 }, raiseApplied: { $ne: true } }, { $inc: { salary: 1000 }, $set: { raiseApplied: true } } )
updateMany() modifica los documentos employee coincidentes de forma individual. Las actualizaciones individuales de documentos son operaciones atómicas, pero la operación updateMany() en su totalidad no es atómica.
Si la operación no logra actualizar todos los documentos coincidentes, puedes volver a ejecutar de forma segura un comando idempotente hasta que no haya documentos adicionales que coincidan con el filtro especificado. En este caso, el campo salary de cada documento se actualiza solo una vez, sin importar cuántas veces se reintente, porque el comando es idempotente.
Después de que todos los empleados elegibles hayan recibido sus aumentos, puedes eliminar el campo raiseApplied con el siguiente comando:
db.employees.updateMany( { }, { $unset: { raiseApplied: 1 } } )
Actualiza varios documentos
La colección restaurant contiene los siguientes documentos:
db.restaurant.insertMany( [ { _id: 1, name: "Central Perk Cafe", violations: 3 }, { _id: 2, name: "Rock A Feller Bar and Grill", violations: 2 }, { _id: 3, name: "Empire State Sub", violations: 5 }, { _id: 4, name: "Pizza Rat's Pizzaria", violations: 8 }, ] )
La siguiente operación actualiza todos los documentos donde las violations son mayores que 4 y $set una marca para revisar:
try { db.restaurant.updateMany( { violations: { $gt: 4 } }, { $set: { "Review" : true } } ); } catch (e) { print(e); }
La operación arroja:
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
La colección ahora contiene los siguientes documentos:
{ _id: 1, name: "Central Perk Cafe", violations: 3 } { _id: 2, name: "Rock A Feller Bar and Grill", violations: 2 } { _id: 3, name: "Empire State Sub", violations: 5, Review: true } { _id: 4, name: "Pizza Rat's Pizzaria", violations: 8, Review: true }
Si no se encuentra ninguna coincidencia, la operación arroja lo siguiente:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }
Al configurar upsert: true se insertaría un documento si no se encuentra ninguna coincidencia.
Actualiza con el pipeline de agregación
El db.collection.updateMany() puede utilizar un pipeline de agregación para actualizar. La pipeline puede constar de las siguientes etapas:
$addFieldsy su alias$set$replaceRooty su alias$replaceWith
El uso de un pipeline de agregación permite una instrucción de actualización más expresiva, como expresar actualizaciones condicionales basadas en los valores actuales de los campos o actualizar un campo con el valor de otros campos.
Ejemplo 1: actualización con el pipeline de agregación mediante campos existentes
Los siguientes ejemplos utilizan el pipeline de agregación para modificar un campo mediante los valores de los otros campos del documento.
Crea una colección students con los siguientes documentos:
db.students.insertMany( [ { _id: 1, student: "Skye", points: 75, commentsSemester1: "great at math", commentsSemester2: "loses temper", lastUpdate: ISODate("2019-01-01T00:00:00Z") }, { _id: 2, students: "Elizabeth", points: 60, commentsSemester1: "well behaved", commentsSemester2: "needs improvement", lastUpdate: ISODate("2019-01-01T00:00:00Z") } ] )
Suponga que, en lugar de los campos commentsSemester1 y commentsSemester2 separados, desea reunirlos en un nuevo campo comments. La siguiente operación de actualización utiliza una canalización de agregación para:
añade el nuevo campo
commentsy establece el campolastUpdate.eliminar los campos
commentsSemester1ycommentsSemester2de todos los documentos en la colección.
db.students.updateMany( { }, [ { $set: { comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } }, { $unset: [ "commentsSemester1", "commentsSemester2" ] } ] )
Nota
En esta pipeline, $set y $unset son etapas de agregación, a diferencia de los operadores de actualización. Las etapas de agregación $set y $unset añaden nuevos campos a los documentos y no modifican los valores de los campos existentes.
Para obtener más información sobre los operadores de actualización, consulta $set y $unset.
- Primera etapa
La etapa
$set:crea un nuevo campo de arreglo
commentscuyos elementos son el contenido actual de los camposcommentsSemester1ycommentsSemester2yestablece el campo
lastUpdateal valor de la variable de agregaciónNOW. La variable de agregaciónNOWse resuelve al valor actual de la fecha y hora y permanece igual a lo largo de toda la pipeline de agregación. Para acceder a las variables de agregación, prefija la variable con signos double de dólar$$y enciérrela entre comillas.
- Segunda etapa
- La etapa
$unsetremueve los camposcommentsSemester1ycommentsSemester2.
Después del comando, la colección contiene los siguientes documentos:
{ _id: 1, student: "Skye", status: "Modified", points: 75, lastUpdate: ISODate("2020-01-23T05:11:45.784Z"), comments: [ "great at math", "loses temper" ] } { _id: 2, student: "Elizabeth", status: "Modified", points: 60, lastUpdate: ISODate("2020-01-23T05:11:45.784Z"), comments: [ "well behaved", "needs improvement" ] }
Ejemplo 2: actualización con un pipeline de agregación mediante los campos existentes de forma condicional
La pipeline de agregación permite que la actualización realice actualizaciones condicionales basadas en los valores actuales de los campos y también utilice estos valores para calcular un valor diferente para otro campo.
Por ejemplo, crea una colección students3 con los siguientes documentos:
db.students3.insertMany( [ { _id: 1, tests: [ 95, 92, 90 ], lastUpdate: ISODate("2019-01-01T00:00:00Z") }, { _id: 2, tests: [ 94, 88, 90 ], lastUpdate: ISODate("2019-01-01T00:00:00Z") }, { _id: 3, tests: [ 70, 75, 82 ], lastUpdate: ISODate("2019-01-01T00:00:00Z") } ] )
Al utilizar un pipeline de agregación, puedes actualizar los documentos con el promedio de calificaciones calculado y la calificación en letras.
db.students3.updateMany( { }, [ { $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] } , lastUpdate: "$$NOW" } }, { $set: { grade: { $switch: { branches: [ { case: { $gte: [ "$average", 90 ] }, then: "A" }, { case: { $gte: [ "$average", 80 ] }, then: "B" }, { case: { $gte: [ "$average", 70 ] }, then: "C" }, { case: { $gte: [ "$average", 60 ] }, then: "D" } ], default: "F" } } } } ] )
Nota
En esta pipeline, $set y $unset son etapas de agregación, a diferencia de los operadores de actualización. Las etapas de agregación $set y $unset añaden nuevos campos a los documentos y no modifican los valores de los campos existentes.
Para obtener más información sobre los operadores de actualización, consulta $set y $unset.
- Primera etapa
La etapa
$set:calcula un nuevo campo
averagebasado en el promedio del campotests. Consulta$avgpara obtener más información sobre el operador de agregación$avgy$truncpara obtener más información sobre el operador de agregación de truncamiento$trunc.establece el campo
lastUpdateal valor de la variable de agregaciónNOW. La variable de agregaciónNOWse resuelve al valor actual de la fecha y hora y permanece igual a lo largo de toda la pipeline de agregación. Para acceder a las variables de agregación, prefija la variable con signos double de dólar$$y enciérrela entre comillas.
- Segunda etapa
- La etapa
$setcalcula un nuevo campogradebasado en el campoaveragecalculado en la etapa anterior. Consulta$switchpara obtener más información sobre el operador de agregación$switch.
Después del comando, la colección contiene los siguientes documentos:
{ _id: 1, tests: [ 95, 92, 90 ], lastUpdate: ISODate("2020-01-24T17:31:01.670Z"), average: 92, grade: "A" } { _id: 2, tests: [ 94, 88, 90 ], lastUpdate: ISODate("2020-01-24T17:31:01.670Z"), average: 90, grade: "A" } { _id: 3, tests: [ 70, 75, 82 ], lastUpdate: ISODate("2020-01-24T17:31:01.670Z"), average: 75, grade: "C" }
Actualiza múltiples documentos con inserción
La colección inspectors contiene los siguientes documentos:
db.inspectors.insertMany( [ { _id: 92412, inspector: "F. Drebin", Sector: 1, Patrolling: true }, { _id: 92413, inspector: "J. Clouseau", Sector: 2, Patrolling: false }, { _id: 92414, inspector: "J. Clouseau", Sector: 3, Patrolling: true }, { _id: 92415, inspector: "R. Coltrane", Sector: 3, Patrolling: false } ] )
La siguiente operación actualiza todos los documentos con Sector mayor que 4 e inspector igual a "R. Coltrane":
try { db.inspectors.updateMany( { "Sector" : { $gt : 4 }, "inspector" : "R. Coltrane" }, { $set: { "Patrolling" : false } }, { upsert: true } ); } catch (e) { print(e); }
La operación arroja:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : ObjectId("56fc5dcb39ee682bdc609b02"), "upsertedCount": 1 }
La colección ahora contiene los siguientes documentos:
{ _id: 92412, inspector: "F. Drebin", Sector: 1, Patrolling: true }, { _id: 92413, inspector: "J. Clouseau", Sector: 2, Patrolling: false }, { _id: 92414, inspector: "J. Clouseau", Sector: 3, Patrolling: true }, { _id: 92415, inspector: "R. Coltrane", Sector: 3, Patrolling: false }, { _id: ObjectId("56fc5dcb39ee682bdc609b02"), inspector: "R. Coltrane", Patrolling: false }
Dado que ningún documento coincidió con el filtro y upsert era true, updateMany() insertó el documento con un _id generado, las condiciones de igualdad del filter y los modificadores update.
Actualizar con nivel de confirmación de escritura (Write Concern)
Dado un set de réplicas de tres nodos, la siguiente operación especifica un w de majority y un wtimeout de 100:
try { db.restaurant.updateMany( { "name" : "Pizza Rat's Pizzaria" }, { $inc: { "violations" : 3}, $set: { "Closed" : true } }, { w: "majority", wtimeout: 100 } ); } catch (e) { print(e); }
Si el reconocimiento tarda más que el límite de wtimeout, se obtiene la siguiente excepción:
WriteConcernError({ "code" : 64, "errmsg" : "waiting for replication timed out", "errInfo" : { "wtimeout" : true, "writeConcern" : { "w" : "majority", "wtimeout" : 100, "provenance" : "getLastErrorDefaults" } } })
La siguiente tabla explica los posibles valores de errInfo.writeConcern.provenance:
Origen | Descripción |
|---|---|
| El nivel de confirmación de escritura se especificó en la aplicación. |
| El nivel de confirmación de escritura se originó a partir de un valor por defecto personalizado. Vea |
| El nivel de confirmación de escritura se originó en el campo |
| El nivel de confirmación de escritura (write concern) se originó en el servidor en ausencia de todas las demás especificaciones de nivel de confirmación de escritura (write concern). |
Especificar la intercalación
La intercalación permite a los usuarios especificar reglas propias del lenguaje para la comparación de strings, como reglas para el uso de mayúsculas y minúsculas y marcas de acento.
Una colección myColl tiene los siguientes documentos:
db.myColl.insertMany( [ { _id: 1, category: "café", status: "A" }, { _id: 2, category: "cafe", status: "a" }, { _id: 3, category: "cafE", status: "a" } ] )
La siguiente operación incluye la opción de intercalación:
db.myColl.updateMany( { category: "cafe" }, { $set: { status: "Updated" } }, { collation: { locale: "fr", strength: 1 } } );
Especifique arrayFilters para una operación de actualización de matriz
Al actualizar el campo de un arreglo, puede especificar arrayFilters que determinen qué elementos del arreglo actualizar.
Se deben actualizar los elementos que coinciden con los criterios arrayFilters
Cree una colección students con los siguientes documentos:
db.students.insertMany( [ { _id: 1, grades: [ 95, 92, 90 ] }, { _id: 2, grades: [ 98, 100, 102 ] }, { _id: 3, grades: [ 95, 110, 100 ] } ] )
Para actualizar todos los elementos que son mayores o iguales a 100 en el arreglo grades, utiliza el operador posicional filtrado $[<identifier>] con la opción arrayFilters:
db.students.updateMany( { grades: { $gte: 100 } }, { $set: { "grades.$[element]" : 100 } }, { arrayFilters: [ { "element": { $gte: 100 } } ] } )
Después de la operación, la colección contiene los siguientes documentos:
{ _id: 1, grades: [ 95, 92, 90 ] } { _id: 2, grades: [ 98, 100, 100 ] } { _id: 3, grades: [ 95, 100, 100 ] }
Actualiza elementos específicos de un arreglo de documentos
Cree una colección students2 con los siguientes documentos:
db.students2.insertMany( [ { _id: 1, grades: [ { grade: 80, mean: 75, std: 6 }, { grade: 85, mean: 90, std: 4 }, { grade: 85, mean: 85, std: 6 } ] }, { _id: 2, grades: [ { grade: 90, mean: 75, std: 6 }, { grade: 87, mean: 90, std: 3 }, { grade: 85, mean: 85, std: 4 } ] } ] )
Para modificar el valor del campo mean para todos los elementos del arreglo grades, donde la calificación sea mayor o igual a 85, utiliza el operador posicional filtrado $[<identifier>] con arrayFilters:
db.students2.updateMany( { }, { $set: { "grades.$[elem].mean" : 100 } }, { arrayFilters: [ { "elem.grade": { $gte: 85 } } ] } )
Después de la operación, la colección tiene los siguientes documentos:
{ _id: 1, grades: [ { grade: 80, mean: 75, std: 6 }, { grade: 85, mean: 100, std: 4 }, { grade: 85, mean: 100, std: 6 } ] } { _id: 2, grades: [ { grade: 90, mean: 100, std: 6 }, { grade: 87, mean: 100, std: 3 }, { grade: 85, mean: 100, std: 4 } ] }
Especifica hint para las operaciones de actualización
Crea una colección de ejemplo students con los siguientes documentos:
db.students.insertMany( [ { _id: 1, student: "Richard", grade: "F", points: 0, comments1: null, comments2: null }, { _id: 2, student: "Jane", grade: "A", points: 60, comments1: "well behaved", comments2: "fantastic student" }, { _id: 3, student: "Ronan", grade: "F", points: 0, comments1: null, comments2: null }, { _id: 4, student: "Noah", grade: "D", points: 20, comments1: "needs improvement", comments2: null }, { _id: 5, student: "Adam", grade: "F", points: 0, comments1: null, comments2: null }, { _id: 6, student: "Henry", grade: "A", points: 86, comments1: "fantastic student", comments2: "well behaved" } ] )
Cree los siguientes índices en la colección:
db.students.createIndex( { grade: 1 } )
La siguiente operación de actualización indica explícitamente que se debe usar el índice {
grade: 1 }:
Nota
Si especifica un índice que no existe, la operación genera un error.
db.students.updateMany( { "points": { $lte: 20 }, "grade": "F" }, { $set: { "comments1": "failed class" } }, { hint: { grade: 1 } } )
El comando de actualización devuelve lo siguiente:
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
Para ver si se utiliza el índice insinuado, ejecuta el pipeline $indexStats :
db.students.aggregate( [ { $indexStats: { } }, { $sort: { name: 1 } }, { $match: {key: { grade: 1 } } } ] )
Errores de nivel de confirmación de escritura (write concern) en clústeres particionados
Cambiado en la versión 8.1.2.
Cuando db.collection.updateMany() se ejecuta en mongos en un clúster fragmentado, siempre se informa de un writeConcernError en la respuesta, incluso cuando se producen uno o más errores adicionales. En versiones anteriores, otros errores a veces causaban que db.collection.updateMany() no reportara errores de nivel de confirmación de escritura.
Por ejemplo, si un documento no supera la validación, activando un error DocumentValidationFailed, y también ocurre un error de nivel de confirmación de escritura, tanto el error DocumentValidationFailed como el writeConcernError se devuelven en el campo de nivel superior de la respuesta.
Roles de usuario y actualizaciones de documentos
A partir de MongoDB 7.0, puedes usar la nueva variable de sistema USER_ROLES para devolver los roles de usuario.
El ejemplo en esta sección muestra actualizaciones de campos en una colección que contiene información médica. El ejemplo lee los roles de usuario actuales de la variable de sistema USER_ROLES y solo realiza las actualizaciones si el usuario tiene un rol específico.
Para usar una variable del sistema, agrega $$ al inicio del nombre de la variable. Especifica la variable del sistema USER_ROLES como $$USER_ROLES.
El ejemplo crea a estos usuarios:
Jamescon un rolBilling.Michellecon un rolProvider.
Realiza los siguientes pasos para crear los roles, los usuarios y la colección:
Crea los roles
Crea roles llamados Billing y Provider con los privilegios y recursos necesarios.
Ejecuta:
db.createRole( { role: "Billing", privileges: [ { resource: { db: "test", collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } ) db.createRole( { role: "Provider", privileges: [ { resource: { db: "test", collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
Inicia sesión como Michelle, quien tiene el rol Provider, y realiza una actualización:
El ejemplo anterior utiliza $setIntersection para devolver documentos donde la intersección entre la string "Provider" y los roles de usuario de $$USER_ROLES.role no está vacía. Michelle tiene el rol Provider, por lo tanto, se realiza la actualización.
A continuación, inicia sesión como James, que no tiene el rol de Provider, e intenta volver a actualizar:
Intento de realizar una actualización
Ejecuta:
// Attempt to update many documents db.medical.updateMany( // User must have the Provider role to perform the update { $expr: { $ne: [ { $setIntersection: [ [ "Provider" ], "$$USER_ROLES.role" ] }, [] ] } }, // Update diagnosisCode { $set: { diagnosisCode: "ACH 02"} } )
El ejemplo anterior no actualiza ningún documento.