Actualizar documentos en MongoDB

Tutorial de MongoDB con JavaEn este nuevo artículo sobre las operaciones CRUD en MongoDB (Create, Read, Update, Delete) se va a ver cómo actualizar documentos en MongoDB. En el último artículo se mostró el uso de cursores en MongoDB para recorrer o iterar la lista de resultados de una búsqueda.

Actualizar documentos en MongoDB

En la actualidad, la API de MongoDB permite 4 forma de actualizar documentos. Para ello, se hace uso principalmente de método update sobre una colección con distintos argumentos según el tipo de actualización que se desee realizar.

Reemplazar documentos en MongoDB

Para reemplazar documentos, el método update necesita dos argumentos: el primero de ellos es la consulta para obtener los documentos, que cumplan el requisito de búsqueda, que se desean actualizar mientras que el segundo argumento indica los nuevos valores de los documentos.

Como ejemplo, se va a buscar los documentos con clave “name” igual a “Bob” y se va a reemplazar por el nuevo documento:

> db.people.update({ name: "Bob" }, { name: "Thomas", salary: 30000 })
> db.people.find({ name: "Thomas"})
{ "_id" : ObjectId("513900c13929ab2874366e50"), "name" : "Thomas", "salary" : 30000 }

Notese como el documento cambia completamente de contenido mostrando ahora los nuevos datos especificados. Ahora, vamos a actualizar de nuevo el documento anterior cambiando su nombre:

> db.people.update({ name: "Thomas" }, { name: "Sandra" })
> db.people.find({ name: "Sandra"})
{ "_id" : ObjectId("513900c13929ab2874366e50"), "name" : "Sandra" }

Con este segundo ejemplo se ve más claro como esta forma de actualizar no actualiza claves concretas sino todo el documento, por ello se ha perdido el campo “salary” que se añadió en la primera actualización.

Otro ejemplo más para terminar:

> db.people.update({ name: "Sandra" }, { name: "Julliet", salary: 50000, age: 28 })
> db.people.find({ name: "Julliet"})
{ "_id" : ObjectId("513900c13929ab2874366e50"), "name" : "Julliet", "salary" : 50000, "age" : 28 }

Actualizando campos de un documento

Sino se desea actualizar los documentos completamente sino sólo algunas claves o partes de ellos se hace uso del operador $set, el cual actualiza sólo los valores de las claves indicadas si existen o, en otro caso, se añaden como nueva información.

Como ejemplo se va a actualizar o añadir una nueva clave “age” con valor 30 al último documento de los ejemplos anteriores:

> db.people.update({ name: "Julliet"}, { $set: { age: 30} })
> db.people.find({ name: "Julliet"})
{ "_id" : ObjectId("513900c13929ab2874366e50"), "name" : "Julliet", "salary" : 50000, "age" : 30 }

Para valores numéricos, como “age”, se puede usar también el operador $inc, el cual incrementa una clave numérica en tantas unidades como se haya especificado:

> db.people.update({ name: "Julliet"}, { $inc: { age: 2} })
> db.people.find({ name: "Julliet"})
{ "_id" : ObjectId("513900c13929ab2874366e50"), "name" : "Julliet", "salary" : 50000, "age" : 32 }

Para terminar este aparado, se va a mostrar cómo eliminar una clave del documento ya que del mismo modo que una clave no existe la crea, se pueden eliminar determinadas claves. Para esto se hace uso del operador $unset:

> db.people.update({ name: "Julliet"}, { $unset: { salary: 1} })
> db.people.find({ name: "Julliet"})
{ "_id" : ObjectId("513900c13929ab2874366e50"), "age" : 32, "name" : "Julliet" }

Como se puede apreciar, al operador $unset se le está pasando la clave a eliminar con un valor “1”. Este valor indica que se debe mantener el orden de las demás claves del documento. Si se especifica a 0, por ejemplo, dicho orden puede verse alterado de forma aleatoria.

Actualizando claves de tipo array

La tercera forma de usar el método update es para actualizar arrays. Para esto se disponen de distintos operadores según la operación que se desee realizar con el array.

Primeramente vamos a insertar un documento con arrays para poder trabajar con él y, en este caso además, se va a indicar el _id del documento de forma explícita:

> db.arrays.insert({ _id: 0, a: [1, 2, 3, 4]})
> db.arrays.find()
{ "_id" : 0, "a" : [ 1, 2, 3, 4 ] }

$set

Para actualizar un único elemento del array se hace uso del operador $set, indicando el elemento o índice del array que se desea actualizar, usando dot notation, y su nuevo valor:

> db.arrays.update({ _id: 0 }, { $set: {"a.2": 5}})
> db.arrays.find()
{ "_id" : 0, "a" : [ 1, 2, 5, 4 ] }

En este caso se ha actualizado “a.2”, el cual es el tercer elemento pues los arrays comienzan por 0. El uso de “dot notacion” es necesario ya que si se intenta hacer mediante acceso directo al array no funciona:

> db.arrays.update({ _id: 0 }, { $set: { a[2]: 6}})
Sat Mar  9 15:35:42 SyntaxError: missing : after property id (shell):1

$push y $pop

Para añadir un nuevo elemento al array se usa el operador $push, indicando el array y el valor del nuevo elemento. Si la clave no contiene un array la operación fallaría:

> db.arrays.update({ _id: 0 }, { $push: { a: 6 }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 1, 2, 5, 4, 6 ] }

Del modo contrario, para eliminar el primer o último elemento del array se usa el operador $pop indicando el elemento del elemento a eliminar. Para eliminar el último elemento se indica el valor “1”:

> db.arrays.update({ _id: 0 }, { $pop: { a: 1 }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 1, 2, 5, 4 ] }

Si se quiere eliminar el primer elemento del array se le indica el valor “-1”:

> db.arrays.update({ _id: 0 }, { $pop: { a: -1 }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 2, 5, 4 ] }

$pushAll, $pull y $pullAll

Para añadir varios valores (un array) de una sola vez a un array existente en el documento se usa el operador $pushAll, indicando la clave y el array con los valores a añadir:

> db.arrays.update({ _id: 0 }, { $pushAll: { a: [7, 8, 9] }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 2, 5, 4, 7, 8, 9 ] }

Para eliminar un elemento del array indicando su valor se usa el operador $pull indicando la clave y el valor del elemento a eliminar:

> db.arrays.update({ _id: 0 }, { $pull: { a: 5 }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 2, 4, 7, 8, 9 ] }

Y para eliminar todas las ocurrencias de distintos valores se usa $pullAll:

> db.arrays.update({ _id: 0 }, { $pullAll: { a: [4, 9] }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 2, 7, 8 ] }

$addToSet

El operador $addToSet es un caso más particular para actualizar arrays ya que inserta un nuevo elemento sólo si no existe ya en el array y, si está, simplemente no hace nada ($pull o $pullAll lo añadirían siempre como un nuevo elemento de igual valor):

> db.arrays.update({ _id: 0 }, { $addToSet: { a: 5 }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 2, 7, 8, 5 ] }
> db.arrays.update({ _id: 0 }, { $addToSet: { a: 5 }})
> db.arrays.find()
{ "_id" : 0, "a" : [ 2, 7, 8, 5 ] }

Como se puede apreciar, en la segunda actualización el array no varía ya que el elmento no ha sido añadido al existir en el array.

Actualizar o añadir un documento

Para terminar, se va a ver una variante muy iteresate para realizar actualizaciones como es el caso de la clausula upsert la cual añade el documento sino existe y, si ya existe, lo actualiza. Esta clausula, que se pasa como tercer argumento al método update, toma los valores true o false para indicar si se desea añadir un documento inexistente o no (por defecto es false)

Para ver un ejemplo se a cambiar el titulo “Dr” por “Mr” a Charlie:

> db.people.update({ "age" : 30, "name" : "Charlie", "title" : "Dr" }, { $set: { title: "Mr"} }, {upsert: true})
> db.people.find( { name: "Charlie"} )
{ "_id" : ObjectId("513900c53929ab2874366e51"), "age" : 30, "name" : "Charlie", "title" : "Mr" }

Si se hace ahora el ejemplo con un documento que no existe éste será añadido:

> db.people.find( { name: "Tommy"} )
> db.people.update({ "age" : 30, "name" : "Tommy" }, { $set: { title: "Mr"} }, {upsert: true})
> db.people.find( { name: "Tommy"} )
{ "_id" : ObjectId("513c746f2bf02d977944f781"), "age" : 30, "name" : "Tommy", "title" : "Mr" }

Conclusión

En este tutorial sobre actualizar documentos en MongoDB se han visto, de forma muy sencilla y mediante bastante ejemplos, los distintos modos de actualizar documentos que provee la API de MongoDB así como los operadores que permiten actualizar claves de tipo array de distintas formas según las necesidades de nuestra aplicación.

Si este artículo le ha resultado interesante y de ayuda le animo a seguir de forma activa el tutorial de MongoDB con Java para seguir profundizando en el uso de una de las bases de datos NoSQL más populares: MongoDB.

Happy Minds!!!

Share on FacebookTweet about this on TwitterShare on LinkedInShare on RedditShare on Google+Digg thisShare on TumblrPin on PinterestBuffer this pagePrint this pageEmail this to someone