Para realizar operaciones de actualización, puede usar la canalización de agregación. Puede crear y ejecutar canalizaciones de agregación para realizar actualizaciones en MongoDB Atlas, MongoDB Compass, MongoDB Shell o controladores.
Con las operaciones de actualización, la canalización de agregación puede consistir en las siguientes etapas:
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.
Nota
Caracteres de dólar en los valores de campo
Cuando utilizas un pipeline de agregación, sanea cualquier cadena que se pase desde la entrada del usuario o se cree dinámicamente a partir del análisis de datos. Si algún valor de campo es un valor literal de string y comienza con un carácter de dólar, el valor debe ser pasado al operador de agregación $literal. El siguiente ejemplo demuestra cómo usar la canalización de agregación $set y el operador $literal para actualizar el documento con un _id de 1 para que tenga un campo cost de $27.
db.inventory.updateOne( { _id: 1 }, [ { $set: { "cost": { $literal: "$27" } } } ] )
Crea una canalización de agregación para actualizar en Atlas
Puedes utilizar la Interfaz de Usuario de MongoDB Atlas para compilar un pipeline de agregación para realizar actualizaciones. Para crear y ejecutar un pipeline de agregación en la interfaz de usuario de MongoDB Atlas, debes tener el rol Project Data Access Read Only o superior.
Accede al Desarrollador de pipelines de agregación.
Selecciona la base de datos para la colección.
El panel principal y Namespaces En el lado izquierdo se enumeran las colecciones de la base de datos.
Seleccione la colección.
Selecciona la colección en el lado izquierdo o en el panel principal. El panel principal muestra las vistas Find, Indexes y Aggregation.
Selecciona la vista de agregación.
Cuando abres por primera vez la vista Aggregation, Atlas muestra una canalización de agregación vacía.
Crea una canalización de agregación para realizar actualizaciones.
Selecciona una etapa de agregación.
Selecciona una etapa de agregación del menú desplegable Select en el panel inferior izquierdo.
El interruptor a la derecha del menú desplegable determina si la etapa está habilitada.
Para realizar actualizaciones con una agregación, utiliza una de estas fases:
Se debe completar la etapa de agregación.
Completa tu etapa con los valores adecuados. Si el Modo de comentario está habilitado, el generador de pipeline proporciona pautas sintácticas para la etapa seleccionada.
A medida que se modifica la etapa, Atlas actualiza los documentos de vista previa a la derecha en función de los resultados de la etapa actual.
Para ejemplos de lo que podría incluir en su etapa de agregación, consulta los ejemplos en esta página.
Añade etapas según sea necesario. Para obtener más información sobre la creación de canalizaciones de agregación en Atlas, consulta Crear una canalización de agregación.
Exporta la canalización de agregación.
Haz clic en Exportar a lenguaje.
Puedes encontrar este botón en la parte superior del desarrollador de pipeline.
Selecciona el lenguaje de exportación que prefieras.
En el menú Export Pipeline To, selecciona el idioma deseado.
El panel My Pipeline a la izquierda muestra el pipeline en la sintaxis de MongoDB Shell. Puedes copiar esto directamente para ejecutar el pipeline en el MongoDB Shell.
El panel de la derecha muestra tu pipeline en el lenguaje seleccionado. Selecciona tu lenguaje preferido.
Selecciona las opciones, si lo deseas.
(Opcional): Selecciona la opción Include Import Statements para incluir las instrucciones de importación necesarias para el lenguaje seleccionado.
(Opcional): Marca la opción Include Driver Syntax para incluir el código específico del controlador para:
Inicializa el cliente
Especifica la base de datos y la colección
Realiza la operación de agregación
Copia el pipeline.
Haz clic en el botón Copy en la parte superior derecha del pipeline para copiar el pipeline del lenguaje seleccionado en tu portapapeles. Pega el pipeline copiado en tu aplicación.
Ejemplos
Los siguientes ejemplos demuestran cómo utilizar las etapas de la canalización de agregación $set, $replaceRoot y $addFields para realizar actualizaciones.
updateOne con $set
Crea una colección students de ejemplo. (Si la colección no existe actualmente, las operaciones de inserción crearán la colección):
db.students.insertMany( [ { _id: 1, test1: 95, test2: 92, test3: 90, modified: new Date("01/05/2020") }, { _id: 2, test1: 98, test2: 100, test3: 102, modified: new Date("01/05/2020") }, { _id: 3, test1: 95, test2: 110, modified: new Date("01/04/2020") } ] )
Para verificar, consulta la colección:
db.students.find()
La siguiente operación de db.collection.updateOne() utiliza una canalización de agregación para actualizar el documento con _id: 3:
db.students.updateOne( { _id: 3 }, [ { $set: { "test3": 98, modified: "$$NOW"} } ] )
Específicamente, el pipeline consiste en una etapa $set que añade el campo test3 (y establece su valor en 98) al documento y establece el campo modified a la fecha y hora actual. La operación utiliza la variable de agregación NOW para la fecha y hora actuales. Para acceder a la variable, prefija con $$ y enciérrala entre comillas.
Para verificar la actualización, puedes hacer query a la colección:
db.students.find().pretty()
updateMany con $replaceRoot y $set
Crea una colección students2 de ejemplo. (Si la colección no existe actualmente, las operaciones de inserción crearán la colección):
db.students2.insertMany( [ { "_id" : 1, quiz1: 8, test2: 100, quiz2: 9, modified: new Date("01/05/2020") }, { "_id" : 2, quiz2: 5, test1: 80, test2: 89, modified: new Date("01/05/2020") }, ] )
Para verificar, consulta la colección:
db.students2.find()
La siguiente db.collection.updateMany() operación utiliza un pipeline de agregación para estandarizar los campos de los documentos (es decir, los documentos de la colección deben tener los mismos campos) y actualiza el campo modified:
db.students2.updateMany( {}, [ { $replaceRoot: { newRoot: { $mergeObjects: [ { quiz1: 0, quiz2: 0, test1: 0, test2: 0 }, "$$ROOT" ] } } }, { $set: { modified: "$$NOW"} } ] )
Específicamente, el pipeline consiste en:
una
$replaceRootetapa con una$mergeObjectsexpresión para establecer valores por defecto para los camposquiz1,quiz2,test1ytest2. La variable de agregaciónROOTse refiere al documento actual que está siendo modificado. Para acceder a la variable, coloca el prefijo$$y enciérralo entre comillas. Los campos actuales del documento sobrescribirán los valores por defecto.una etapa
$setpara actualizar el campomodifieda la fecha y hora actuales. La operación utiliza la variable de agregaciónNOWpara la fecha y hora actuales. Para acceder a la variable, coloca el prefijo$$y enciérralo entre comillas.
Para verificar la actualización, puedes hacer query a la colección:
db.students2.find()
updateMany con $set
Crea una colección students3 de ejemplo. (Si la colección no existe actualmente, las operaciones de inserción crearán la colección):
db.students3.insertMany( [ { "_id" : 1, "tests" : [ 95, 92, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "tests" : [ 94, 88, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 3, "tests" : [ 70, 75, 82 ], "modified" : ISODate("2019-01-01T00:00:00Z") } ] );
Para verificar, consulta la colección:
db.students3.find()
La siguiente operación db.collection.updateMany() utiliza una canalización de agregación para actualizar los documentos con el promedio de calificaciones calculado y la calificación en letra.
db.students3.updateMany( { }, [ { $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] }, modified: "$$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" } } } } ] )
Específicamente, el pipeline consiste en:
una
$setetapa para calcular el valor promedio truncado de los elementos del arreglotestsy para actualizar el campomodifieda la fecha y hora actual. Para calcular el promedio truncado, la etapa utiliza las expresiones$avgy$trunc. La operación utiliza la variable de agregaciónNOWpara la fecha y hora actuales. Para acceder a la variable, coloca el prefijo$$y enciérralo entre comillas.una
$setetapa para agregar el campogradebasado en elaverageusando la expresión$switch.
Para verificar la actualización, puedes hacer query a la colección:
db.students3.find()
updateOne con $set
Crea una colección students4 de ejemplo. (Si la colección no existe actualmente, las operaciones de inserción crearán la colección):
db.students4.insertMany( [ { "_id" : 1, "quizzes" : [ 4, 6, 7 ] }, { "_id" : 2, "quizzes" : [ 5 ] }, { "_id" : 3, "quizzes" : [ 10, 10, 10 ] } ] )
Para verificar, consulta la colección:
db.students4.find()
La siguiente operación db.collection.updateOne() utiliza una canalización de agregación para añadir puntuaciones de cuestionarios al documento con _id:
2:
db.students4.updateOne( { _id: 2 }, [ { $set: { quizzes: { $concatArrays: [ "$quizzes", [ 8, 6 ] ] } } } ] )
Para verificar la actualización, consulta la colección:
db.students4.find()
updateMany con $addFields
Crea una colección de ejemplo temperatures que contenga temperaturas en Celsius (si la colección no existe actualmente, las operaciones de inserción crearán la colección):
db.temperatures.insertMany( [ { "_id" : 1, "date" : ISODate("2019-06-23"), "tempsC" : [ 4, 12, 17 ] }, { "_id" : 2, "date" : ISODate("2019-07-07"), "tempsC" : [ 14, 24, 11 ] }, { "_id" : 3, "date" : ISODate("2019-10-30"), "tempsC" : [ 18, 6, 8 ] } ] )
Para verificar, consulta la colección:
db.temperatures.find()
La siguiente db.collection.updateMany() operación utiliza una canalización de agregación para actualizar los documentos con las temperaturas correspondientes en Fahrenheit:
db.temperatures.updateMany( { }, [ { $addFields: { "tempsF": { $map: { input: "$tempsC", as: "celsius", in: { $add: [ { $multiply: ["$$celsius", 9/5 ] }, 32 ] } } } } } ] )
Específicamente, el pipeline consiste en una etapa $addFields para añadir un nuevo campo de arreglo tempsF que contiene las temperaturas en Fahrenheit. Para convertir cada temperatura en grados Celsius del arreglo tempsC a Fahrenheit, la etapa utiliza la expresión $map con la expresión $add y la expresión $multiply.
Para verificar la actualización, puedes hacer query a la colección:
db.temperatures.find()
Actualiza con variables let
Nuevo en la versión 5.0.
Para definir variables a las que puedas acceder en otras partes del comando, utiliza la opción let.
Nota
Para filtrar los resultados usando una variable, debes acceder a la variable dentro del operador $expr.
Cree una colección cakeFlavors:
db.cakeFlavors.insertMany( [ { _id: 1, flavor: "chocolate" }, { _id: 2, flavor: "strawberry" }, { _id: 3, flavor: "cherry" } ] )
El siguiente comando updateOne utiliza variables configuradas con la opción let:
La variable
targetFlavorestá configurada encherry. Esta variable se utiliza en la expresión$eqpara especificar el filtro de coincidencia.La variable
newFlavorestá configurada enorange. Esta variable se utiliza en el operador$setpara especificar el valorflavoractualizado del documento coincidente.
db.cakeFlavors.updateOne( { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, [ { $set: { flavor: "$$newFlavor" } } ], { let: { targetFlavor: "cherry", newFlavor: "orange" } } )
Después de ejecutar la operación de actualización anterior, la colección cakeFlavors contiene los siguientes documentos:
[ { _id: 1, flavor: 'chocolate' }, { _id: 2, flavor: 'strawberry' }, { _id: 3, flavor: 'orange' } ]
Ejemplos adicionales
Consulta también las diversas páginas de métodos de actualización para ejemplos adicionales: