Skip to content

MongoDB. Primeros pasos

2 junio 2013

logoMongoDB

En esta entrada vamos a ver aspectos muy básicos de configuración de MongoDB que nos aporten los conocimientos de base para poder empezar a crear aplicaciones mucho más complejas que utilicen esta tecnología de almacenamiento no relacional. Los puntos que veremos son:

  1. Introducción a MongoDB (Teórica pero ligera)
  2. Cómo instalar un servidor MongoDB en nuestro equipo local
  3. Probar la consola de MongoDB
  4. Crear nuestra primera Base de Datos y nuestra primera Colección
  5. Insertar documentos
  6. Consultar documentos
  7. Actualizar documentos
  8. Eliminar documentos
  9. Lecturas recomendadas

Empecemos 🙂

1. Introducción a MongoDB

MongoDB es una base de datos no relacional orientada a Documentos destinada a almacenar información de manera ágil y flexible. Pero ¿esto que significa exactamente?

Si miramos los modelos de almacenamiento de información relacional (MySQL, PostgreSQL, SQL Server…) comprobaremos que el modelo relacional impone esquemas planos y rígidos para almacenar nuestra información a modo de Tablas. Como sabéis, una Tabla está formada por filas y cada fila tiene exactamente el mismo número de atributos que vienen impuestos por la definición del Esquema de la propia tabla. De forma que: ¿Qué ocurre si una fila requiere un atributo extra? ¿Modificamos todo el esquema para una única fila?

MongoDB carece de esquema, de manera que cada documento que insertemos en nuestra Base de Datos tendrá el formato que más se adapte a los requisitos de la aplicación, sin restricciones de claves ni atributos predefinidos. MongoDB reemplaza el concepto de Fila (rígida) por el concepto de Documento (flexible).

Un Documento nos permitirá almacenar la información de un modo mucho más flexible, ya que cada Documento está compuesto por pares de clave/valor. Esos valores podrán ser valores simples o valores complejos, mediante los cuales podremos incrustrar dos tipos de elementos dentro del propio Documento: un Array de valores (simples y complejos) y otros Documentos. De este modo la información se almacena con una estructura jerárquica mucho más compleja y se representa de modo que se adapta de forma más natural a cómo trabajamos con los objetos en memoria en nuestras aplicaciones. Podríamos pensar en un Documento como un Map<String, Object> de Java.

Los Documentos se representan en JSON, pero MongoDB utiliza un formato binario para gestionar esos JSON, conocido como BSON.

Bueno basta de teoría y vayamos al grano, a ensuciarnos las manos 😉

2. Cómo instalar un servidor MongoDB en nuestro equipo local

Vamos a ver cómo instalar un servidor de MongoDB en Mac, la instalación para Windows o Linux, será muy parecida, así es que una vez sabiendo los pasos para instalarlo en una plataforma concreta, no debería haber mayor problema para instalarlo en otra.

El primer paso, será obviamente descargarnos la distribución de MongoDB adecuada para nuestra plataforma. Para ello vamos a la web de descargas de MongoDB (http://www.mongodb.org/downloads) y descargamos la versión para Mac en este caso.

Lo que descargaremos será un fichero .tgz que tendrá empaquetados todos los ficheros que necesitaremos para levantar nuestro servidor MongoDB.

Una vez finalizada la descarga, abrimos una ventana de Terminal y vamos a la carpeta en la que se ha descargado el fichero .tgz y lo descomprimimos ejecutando el siguiente comando:

tar xvf mongodb-osx-x86_64-X.Y.Z.tgz

NOTA: X.Y.Z Hace referencia a la versión que os hayáis descargado, lo ideal es descargar siempre la última disponible.

Una vez que se haya desempaquetado y descomprimido todo, ya casi tendremos nuestro servidor listo para iniciarse. Si entramos dentro del directorio ‘mongodb-osx-x86_64-X.Y.Z‘ veremos que hay una carpeta ‘bin‘. Esta carpeta contendrá todos los ejecutables binarios que necesitaremos para ejecutar MongoDB. Entre ellos, tendremos:

  1. mongod: Binario para levantar el servidor de MongoDB
  2. mongo: Binario con el que podremos ejecutar Mongo Shell y conectarnos al servidor levantado con mongod

De base, MongoDB guarda su configuración y sus datos en el directorio: /data/db (aunque puede cambiarse al arrancar el servidor utilizando la opción –dbpath al ejecutar mongod)

Si este directorio no existe, al arrancar el servidor de MongoDB obtendremos un error indicándolo. Por tanto, como estamos instalando todo de cero, lo más normal es que aún no tengáis este directorio en vuestro equipo así es que vamos a crearlo.

sudo mkdir -p /data/db

Como vamos a tocar el directorio raíz (/), necesitaremos privilegios de root, por eso ejecutamos el comando con ‘sudo’ delante. Os solicitará vuestra contraseña de usuario.

MongoDB necesitará ciertos permisos para leer y escribir en este directorio; para no complicarlo mucho, y presuponiendo que vamos a instalar MongoDB en un entorno de desarrollo, vamos a darle permisos totales a este directorio (en un entorno de producción, habrá que tener más cuidado con los permisos de este directorio):

sudo chmod 777 /data/db

Ya lo tenemos todo listo para arrancar nuestro servidor de MongoDB y para ello, si recordáis, disponemos del ejecutable mongod. Volvemos a la carpeta donde desempaquetamos nuestro fichero .tgz, entramos en el directorio bin/ y arrancamos nuestro servidor.

./mongod

3. Probar la consola de MongoDB

Una vez que tenemos nuestro servidor ejecutándose en nuestro entorno local de desarrollo, podremos conectarnos a él mediante la consola de Mongo (Mongo Shell) o mediante el Driver de Java.

Para conectarnos mediante Mongo Shell abrimos una nueva ventana o pestaña de Terminal y volvemos al directorio en el que se encuentran todos los binarios de Mongo: mongodb-osx-x86_64-X.Y.Z/bin

Una vez en esa carpeta, podemos lanzar la Consola de MongoDB:

./mongo

La consola es totalmente interactiva y a partir de este momento ya podemos escribir comandos que serán ejecutados contra nuestro servidor de MongoDB. Además si os fijáis, veréis que al conectaros a la consola de Mongo, os aparece la versión actual y la base de datos a la que estáis conectados. Por defecto, Mongo Shell se conecta contra la base de datos ‘test’.

Podemos probar a ejecutar nuestro primer comando para saber qué bases de datos existen en nuestro servidor.  Para ello:

show dbs

Si queremos utilizar una en particular y ver cuántas colecciones tiene esa base de datos, ejecutaremos los comandos siguientes:

use <nombre de la base de datos>
show collections

Si queremos mostrar la base de datos que estamos utilizando actualmente:

db

4. Crear nuestra primera Base de Datos y nuestra primera Colección

Bien, vamos a empezar creando nuestra primera base de datos y vamos a añadirle colecciones y documentos.

En MongoDB no hay un comando específico para crear una Base de Datos, simplemente tenemos que decirle mediante la Shell que utilice esa base de datos que todavía no existe e insertar algún documento en una colección que todavía no existe. Veamos un ejemplo:

use blogdb
db (confirmamos que estamos utilizando la base de datos blogdb)
db.posts.insert( {'title':'Nueva Entrada', 'likes':0} )

A partir de este momento, MongoDB habrá creado una Base de Datos llamada ‘blogdb’, una Colección dentro de esa base de datos llamada ‘posts’ y además habrá insertado un Documento en la Colección que únicamente tiene el campo ‘title’ y el campo ‘likes’.

Podemos crear colecciones de forma mucho más personalizada y configurar diversas opciones haciendo uso del siguiente comando:

db.createCollection("log",{})

Como veis, estamos creando la colección ‘log’ y además estamos pasando un segundo parámetro (que será un Documento) con las opciones que nos interesa configurar en nuestra colección. En la documentación oficial, tenéis disponibles todas las opciones que podéis añadir al documento de configuración.

Veamos cómo podemos insertar nuevos documentos en nuestra colección.

5. Insertar Documentos

En el punto anterior ya vimos brevemente la función ‘insert()‘ para insertar documentos en nuestra colección. Vamos a indagar un poco más sobre ella y vamos a insertar nuevos documentos en nuestra colección, que posteriormente podremos consultar.

La función ‘insert()‘ admite un solo parámetro que podrá ser: Un Documento o un Array de Documentos.

Cada Documento en MongoDB tiene una clave primaria, un identificador único. Esta clave primaria (PK) se identifica con el nombre _id y si el Documento que estamos insertando no contiene este campo, Mongo lo añadirá por nosotros (como en el ejemplo del punto anterior). Por tanto, podemos añadir explícitamente este campo, o dejar que MongoDB lo añada automáticamente. Si decidimos utilizar un ‘_id‘ propio, debemos asegurarnos que el valor que asignemos a ‘_id‘ sea único en nuestra Colección.

Vamos a añadir un nuevo documento a nuestra colección de blogs:

db.posts.insert( { 'title':'Entrada con más campos', 
                   'desc':'Entrada que contiene más info', 
                   'date':'01-06-2013', 
                   'likes':0 } )

Como veis estamos insertando un nuevo Documento en nuestra colección de ‘posts‘ que no tiene la misma estructura que el Documento que insertamos previamente; esta es la ventaja de trabaja con un sistema de Bases de Datos sin esquemas rígidos.

Podríamos insertar un Array de Documentos:

db.posts.insert([ {'title':'E1','likes':0}, 
                  {'title':'E2','likes':0}, 
                  {'title':'E3', 'date':'01-06-2013','likes':0} ])

NOTA: Pongo los Documentos pequeños para que se lea mejor, pero tened en cuenta que los Documentos pueden ser de hasta 16 Mb. (Si utilizamos el sistema de ficheros GridFS, este límite de tamaño será mayor). Aquí podéis ver otros límites que tiene MongoDB.

Esta segunda opción de inserción, se conoce como Inserción Batch y está especialmente diseñada para ofrecer un mayor rendimiento a la hora de escribir un conjunto grande de Documentos en nuestra Colección.

Bueno, ya que tenemos algunos documentos en nuestra Base de Datos, vamos a consultarlos.

6. Consultar Documentos

Sin duda, MongoDB demuestra su gran potencial en la riqueza de las consultas que podemos lanzar para obtener 1 o varios documentos que cumplan con los requisitos que busquemos. En este punto no vamos a ver todas las posibilidades que ofrecen las Queries en Mongo (ya que hay material suficiente para escribir una entrada con ello), pero sí vamos a introducir lo más común y a enredar un poco con ello.

Podemos lanzar Queries contra la base de datos con los métodos find() y findOne() y un Documento de Query como parámetro que será el que especifique los requisitos que buscamos.

Podemos lanzar Queries con el operador condicional $, para consultar por rangos, inclusiones en conjuntos, etc…

Cada Query devuelve un cursor a la base de datos con el que podremos seguir consultando en bloques, los documentos que ha devuelto la query.

6.1 Introducción a find() y findOne()

El método find se utiliza para realizar Queries en MongoDB. Devuelve un subconjunto de Documentos dentro de una Colección o ningún Documento, si no ha sido capaz de encontrar ninguno bajo los criterios especificados.

Podemos pasar dos parámetros al método find({1}, {2}):

  1. Especifica la Query a realizar.
  2. Especifica qué claves del Documento queremos mostrar. De forma que mostremos sólo la información del Documento que nos interesa y evitamos traer el Documento entero.

Estos parámetros se expresan en forma de Documento BSON.

El método más sencillo para lanzar una consulta contra la Base de Datos, es preguntar por valores exactos de uno o más campos:

db.posts.find({'title' : 'Nueva Entrada'})
db.posts.find({'title' : 'Entrada con más campos'})
db.posts.find({'title':'E1', 'likes' : 5})

Podemos indicarle a MongoDB que realice una consulta contra la Base de Datos pero que no aplique ninguna restricción, es decir que nos devuelva todos los Documentos que contiene. Para ello utilizamos el método find() sin parámetros o pasándole un único parámetro que será el Documento vacío:

db.posts.find()   ó   db.posts.find({})

Podemos indicarle que nos muestre todos los documentos de la Colección, pero que únicamente nos muestre el título de cada Documento:

db.posts.find({},{"title" : 1})

De este modo obtenemos todos los Documentos, pero únicamente se muestra el Título. Aunque esto no es verdad del todo, ya que si lanzáis la Query, veréis que también se muestra el atributo “_id”. Por defecto, MongoDB siempre muestra esta clave en los resultados de búsqueda, si no nos interesa que aparezca, debemos indicarle de forma expresa que lo filtre:

db.posts.find({},{"title" : 1, "_id" : 0})

Si por el contrario, quisiéramos que la Query nos mostrara todos los campos de cada Documento excepto la fecha, por ejemplo, lo expresaríamos del siguiente modo:

db.posts.find({},{"date" : 0})

findOne() Puede utilizarse del mismo modo que find() pero sólo devuelve un Documento.

6.2 Criterios de Query

Pero realmente las Queries en Mongo pueden ir mucho más allá de consultar valores exactos (que en muchas ocasiones nos servirán de poco). Las Queries pueden utilizar criterios mucho más complejos como rangos, cláusulas OR y negaciones.

$lt“, “$lte“, “$gt” y “$gte” son operadores de comparación que corresponden a <, <=, >, y >=, respectivamente. Podemos combinarlos en nuestras queries para buscar por rango de valores. Por ejemplo para buscar los Documentos que tengan más de 5 ‘likes’, podríamos utilizar la siguiente Query:

db.posts.find({'likes' : {'$gt' : 5} })

Para buscar Documentos que tengan entre 10 y 15 ‘likes’ podríamos utilizar la siguiente Query:

db.posts.find({'likes' : {'$gte' : 10, '$lte' : 15} })

Podemos utilizar también el operador de negación “$ne“. Por ejemplo para buscar los Documentos cuyo título no sea ‘E1’, podemos lanzar la siguiente Query:

db.posts.find({'title' : {'$ne' : 'E1'} })

$ne” podemos utilizarlo con cualquier tipo de dato. Por ejemplo, para buscar  los Documentos que tengan algún ‘likes’:

db.posts.find({'likes' : {'$ne' : 0} })

Un Operador interesante en MongoDB es “$in“, que nos permitirá preguntar por una serie de valores para una única clave. Por ejemplo, si queremos lanzar una Query para buscar los Documentos que tengan un valor de ‘likes‘ que sea 5,6 ó 7, podemos hacer lo siguiente:

db.posts.find({'likes' : {'$in' : [5,6,7]} })

El opuesto a “$in” es “$nin” que devuelve los Documentos que no encajan con ninguno de los valores del Array de criterios. Si quisiéramos preguntar por Documentos cuyo valor de ‘likes‘ no fuera ni 5, ni 6 ni 7, haríamos:

db.posts.find({'likes' : {'$nin' : [5,6,7]} })

Otro Operador muy interesante en MongoDB es el Operador OR. Es más general que “$in” y puede utilizarse para consultar por cualquiera de los valores dados para diferentes claves del Documento; al contrario que $in que consultaba una única clave. El operador OR ($or) admite un Array de diversos criterios que pueden consultar diversas claves del Documento. Por ejemplo, para consultar los Documentos cuyo ‘title‘ sea ‘E2’ o su número de ‘likes‘ sea mayor que 5, podríamos hacer:

db.posts.find({'$or' : [ {'title' : 'E2'}, {'likes' : {'$gt': 5}} ] })

$exists devuelve los Documentos que tengan un campo determinado. Por ejemplo:

db.posts.find({'desc' : {'$exists' : true} })

O al contrario, aquellos Documentos que no tengan un campo determinado:

db.posts.find({'desc' : {'$exists' : false} })

$type devuelve los Documentos cuyo campo sea del tipo indicado. Por ejemplo para buscar los Documentos cuyo campo ‘title‘ sea de tipo String:

db.posts.find({'title' : {'$type' : 2} })

El tipo de campo se referencia mediante un número entero. En este enlace de la documentación oficial de MongoDB tenéis todas las correspondencias.

6.3 Queries en Arrays

Lanzar Queries contra Documentos que contenga algún campo de tipo Array es muy sencillo. De hecho puede tratarse como un campo más sin importar que sea un Array. Por ejemplo, supongamos que insertamos el siguiente Documento en nuestra Colección, con un nuevo campo ‘tags‘ que contendrá un Array de valores:

db.posts.insert( { 'title':'Entrada con tags', 
                   'desc':'Entrada que contiene tags', 
                   'date':'02-06-2013', 
                   'likes':0, 
                   'tags' : ['mongo', 'blog', 'query'] })

Si quisiéramos consultar los Documentos que tengan el ‘tag‘ ‘mongo’, lo haríamos del siguiente modo:

db.posts.find({'tags' : 'mongo'})

Así de simple, es como si el campo ‘tags’ al lanzar una búsqueda se dividiera y tomara cada elemento de dentro del Array.

Si quisiéramos consular aquellos Documentos que tuvieran el tag ‘mongo’ y el tag ‘blog’ utilizaríamos el operador “$all“.

db.posts.find({'tags' : {$all : ['mongo', 'blog']} })

6.4 Expresiones Regulares

Podemos utilizar expresiones regulares para buscar Documentos con mayor flexibilidad en los campos de tipo cadena. MongoDB utiliza la librería ‘Perl Compatible Regular Expressions (PCRE)‘ para las consultas con expresiones regulares, por tanto cualquier expresión regular válida para PCRE será válida para MongoDB. Al poder realizar Queries con Expresiones Regulares, la capacidad de encontrar campos que cumplan una determinada condición, se amplía enormemente. Por ejemplo, si queremos buscar los Documentos cuyo campo ‘title‘ empiece por ‘Nueva’:

db.posts.find({'title' : /^Nueva/ })

O aquellos Documentos que en su descripción tengan la palabra ‘mongo’ sin importar mayúsculas o minúsculas:

db.posts.find({'desc' : /mongo/i })

6.5 Count, Limit, Skip y Sort

Si queremos conocer la cantidad de Documentos que tenemos almacenados en nuestra Colección, podemos utilizar la función count()

db.posts.count()

Al igual que ‘find()‘, a ‘count()‘ podemos pasarle un parámetros que será un Documento con las restricciones que queremos aplicar a la consulta. Por ejemplo, para saber cuantos Documentos hay con un valor de ‘likes’ mayor de 5:

db.posts.count({'likes' : {'$gt' : 5} })

limit() Sirve para limitar una consulta y devolver un número tope de Documentos. Por ejemplo para devolver sólo 3 elementos podríamos hacer:

db.posts.find().limit(3)

skip() funciona de un modo muy similar a ‘limit()‘ y lo que hace es saltarse el número de Documentos que le especifiquemos y devolver a partir de ahí. Por ejemplo, para ignorar los 3 primeros Documentos y devolver todos los demás:

db.posts.find().skip(3)

Para ordenar el resultado de la consulta, podemos utilizar la función sort(). Esta función recibe un Documento, que le indica cuáles son los campos por los que queremos ordenar y el orden de estos (1 ascendente, -1 descendente). Por ejemplo para ordenar los Documentos de mayor a menor número de ‘likes‘:

db.posts.find().sort({'likes' : -1})

Si quisiéramos además ordenar en modo ascendente por el ‘title‘ del Documento:

db.posts.find().sort({'likes' : -1, 'title' : 1})

Estos tres métodos pueden combinarse, por ejemplo para tareas de paginación; aunque hay que tener cuidado ya que la Query que lancemos puede consumir mucho tiempo de proceso.

Por ejemplo, para conocer los 5 Documentos con mayor número de ‘likes‘:

db.posts.find().limit(5).sort({'likes' : -1})

Con todo esto que os he contado ya tenemos una buena base para lanzar consultas sobre Mongo, pasemos al siguiente punto.

7. Actualizar Documentos

Una vez que un Documento está almacenado en nuestra Base de Datos, podremos modificar el valor de sus campos cuando nos interese utilizando el método update()

El método update() requiere dos parámetros:

  1. Un Documento de Consulta que especifique los criterios para localizar los Documentos a actualizar
  2. Un Documento de Modificación que describe los cambios a realizar sobre los Documentos encontrados

Un dato importante sobre las actualizaciones es que todas las operaciones de actualización son atómicas, lo que significan que si dos actualizaciones suceden en el mismo instante, nunca se llevarán a cabo a la vez, la primera que alcance el servidor se ejecutará primero y luego la otra. Este mecanismo de bloqueo tiene una gran relevancia en MongoDB para evitar Documentos corruptos durante las actualizaciones. Veremos en breve un ejemplo de esto con el operador $inc.

Por defecto, la función update() realiza un reemplazo del Documento que vamos a actualizar, es decir sustituye uno por otro. Por ejemplo, supongamos que queremos actualizar el Documento con ‘title‘ : ‘E1‘ y cambiarle el título por ‘title‘ : ‘E11‘; si hacemos un find() para ver el aspecto de nuestro Documento, encontraríamos algo parecido a:

{
   '_id' : ObjectId("4b2b9f67a1f631733d917a7a"),
   'title':'E1',
   'likes':0
}

Si actualizamos este Documento y llamamos la función update() del siguiente modo:

db.posts.update({'title':'E1'}, {'title':'E11'})

Y volvemos a llamar find() para localizar nuestro Documento, obtendremos algo como lo siguiente:

{
   '_id' : ObjectId("4b2b9f67a1f631733d917a7a"),
   'title':'E11'
}

Como veis, el ‘_id’ no ha variado, sigue siendo el mismo; lo que ha hecho MongoDB ha sido sustituirnos un Documento por otro, eliminando todo rastro del primer Documento. En este caso y como este ejemplo es muy sencillo, puede que no tenga mucha importancia, pero si nuestros Documentos fueran mucho más grandes, con cientos de campos, lo más probable es que no nos interese perder ninguno.

Entonces, ¿Cómo podemos evitar estos reemplazos cuando lo que queremos es actualizar un único campo (o varios)?

7.1 Modificadores

Lo habitual es que únicamente nos interese actualizar ciertos campos del Documento. Estas actualizaciones parciales, se realizan de forma muy eficiente con el uso de Modificadores de actualización atómicos. Estos Modificadores son claves especiales con las que podremos añadir, eliminar y modificar campos del Documento, e incluso manipular Arrays y Documentos incrustados.

En estas ocasiones, la operación de update() se realiza del mismo modo que hemos visto anteriormente, pero el segundo Documento que pasamos por parámetro, llevará incluida la clave de Modificación que nos interese aplicar. Veamos algunas de las claves que podemos utilizar:

$inc: Nos permitirá incrementar el valor de un campo de tipo numérico en las unidades que le especifiquemos. Por ejemplo si quisiéramos incrementar el número de ‘likes‘ que tiene un Documento en concreto haríamos lo siguiente:

db.posts.update({'title':'E11'}, {$inc : {'likes' : 1} })

Si recordáis, este es el Documento que actualizamos previamente y en el que habíamos eliminado el campo ‘likes‘. $inc incrementará el número de ‘likes‘ del Documento y si ese Documento no tiene el campo ‘likes‘ lo crea, lo setea a 0 y lo incrementa en 1.

Antes os he comentado la importancia de que las operaciones de Update se realicen de forma atómica y os he dicho que veríamos un ejemplo más claro con el modificaro $inc. Imaginad que recibimos simultáneamente 100 peticiones de actualización sobre el Documento anterior para incrementar el valor del campo ‘likes‘, lo que nos interesa es que MongoDB sea capaz de sincronizar esas 100 escrituras y que al finalizar, tengamos un valor de 101 para el campo ‘likes‘ de forma que no hayamos perdido ningún incremento. Por eso es importante resaltar el concepto de Actualización Atómica.

$set: Nos permitirá actualizar uno o varios campos de un Documento sin reemplazar el Documento entero. Si el campo que vamos a actualizar no existe, lo crea. Por ejemplo, supongamos que queremos añadir al Documento anterior el campo ‘author‘, haríamos lo siguiente:

db.posts.update({'title':'E11'} , {$set : {'author':'rekkeb'}} )

Si hacemos un find() del Documento, obtendremos algo como esto:

{
   '_id' : ObjectId("4b2b9f67a1f631733d917a7a"),
   'title':'E11',
   'likes': 101,
   'author':'rekkeb'
}

$unset: Realiza la operación inversa a $set, de forma que podremos eliminar un campo y su valor del Documento sin modificar el resto de campos. Si queremos eliminar el campo ‘author‘, haríamos:

db.posts.update({'title':'E11'} , {$unset : {'author':1}} )

Y el Documento nos quedaría:

{
   '_id' : ObjectId("4b2b9f67a1f631733d917a7a"),
   'title':'E11',
   'likes': 101
}

7.1.1 Modificadores de Arrays

$set: También puede utilizarse para modificar los elementos que hay dentro de un Array. Vamos a añadir un Array de Tags al Documento anterior y así podemos ir modificándolo.

db.posts.update({'title':'E11'} , {$set : {'tags':['blog','mongo']}} )

Con lo que nuestro Documento tendría la siguiente forma:

{
   '_id' : ObjectId("4b2b9f67a1f631733d917a7a"),
   'title':'E11',
   'likes': 101,
   'tags' : ['blog', 'mongo']
}

Con $set podremos manipular y sustituir los elementos que se encuentran dentro del Array. Supongamos que queremos sustituir el tag ‘mongo’ por ‘NoSQL’. Con $set podemos acceder a la posición que ocupa el elemento dentro del Array y modificarlo:

db.posts.update({'title':'E11'} , {$set : {'tags.1':'NoSQL'}} )

NOTA: La primera posición del Array es la Cero.

Nuestro Documento actual quedaría:

{
   '_id' : ObjectId("4b2b9f67a1f631733d917a7a"),
   'title':'E11',
   'likes': 101,
   'tags' : ['blog', 'NoSQL']
}

$push: Añade un nuevo elemento al final del Array

db.posts.update({'title':'E11'} , {$push : {'tags':'mongo'}} )

$pop: Elimina el último elemento del Array

db.posts.update({'title':'E11'} , {$pop : {'tags': 1}} )

Si quisiéramos eliminar el primer elemento del Array:

db.posts.update({'title':'E11'} , {$pop : {'tags': -1}} )

$pushAll: Añade al final del Array una nueva lista elementos

db.posts.update({'title':'E11'} , {$pushAll : {'tags':['mongo','bbdd','unix']}} )

$pull: Elimina del Array el elemento cuyo valor coincida con el que nosotros le indiquemos

db.posts.update({'title':'E11'} , {$pull : {'tags':'unix'}} )

$pullAll: Elimina una lista de elementos del Array, cuyos valores coincidan con los que ya existen en el Array

db.posts.update({'title':'E11'} , {$pullAll : {'tags':['mongo','bbdd']}} )

$addToSet: Añade un elemento al Array sólo si este no se encuentra ya presente. Provoca que nuestro Array se comporte como un conjunto (Set) de elementos en el que no se permiten duplicados.

db.posts.update({'title':'E11'} , {$addToSet : {'tags': 'bbdd'}} )

Si añadiéramos el tag ‘blog’ con $addToSet, la operación no tendría efecto ya que ese tag ya existe en el Array:

db.posts.update({'title':'E11'} , {$addToSet : {'tags': 'blog'}} )

7.2 Multiple Update

Todas las operaciones que hemos visto hasta ahora, actualizan un único Documento, ya que la clave por la que estamos buscando ‘title’, es única para cada Documento (se supone).

¿Qué ocurriría si quisiéramos actualizar todos los Documentos que tengan un valor de ‘likes’ a 0 e incrementarlo en 5 en cada uno de los Documentos?

Si lanzamos la operación de update() del siguiente modo:

db.posts.update({'likes':0} , {$inc : {'likes': 5}} )

Veremos que al finalizar el Update, sólo se ha actualizado un Documento, el primero que MongoDB haya encontrado. Entonces, ¿cómo hacemos para que se actualicen todos los Documentos que cumplan el criterio especificado?

Es sencillo, simplemente tenemos que pasar un tercer parámetro a la función de update() que le indique que queremos realizar una Actualización Múltiple. El parámetro es: {multi: true}

De forma que nuestra sentencia de Update quedaría del siguiente modo:

db.posts.update({'likes':0} , {$inc : {'likes': 5}}, {multi:true} )

Y ahora sí podemos comprobar como no queda ningún Documento en nuestra Base de Datos con un valor para ‘likes‘ de 0.

Para conocer el número de Documentos que han sido actualizados tras una operación de Update, podemos lanzar el comando getLastError de MongoDB y bajo la clave ‘n‘, tendremos el dato que buscamos.

db.runCommand({getLastError : 1})

Y obtendremos algo como:

{
  "err" : null, 
  "updatedExisting" : true, 
  "n" : 5, 
  "ok" : true
}

8. Eliminar Documentos

Para eliminar Documentos, en MongoDB tenemos la función remove() que al igual que find(), recibe un parámetro que será un Documento con los criterios para seleccionar aquellos Documentos que nos interesa eliminar de la Colección.

Si ejecutamos la función remove() sin ningún parámetro, eliminaremos todos los Documentos de la Colección, pero la Colección y los índices que se hayan creado permanecerán intactos, estos no se borran. Por ejemplo, para eliminar todos los Documentos que tengan un valor de ‘likes‘ mayor o igual de 100:

db.posts.remove({'likes' : {$gte:100} })

Esta función elimina los Documentos seleccionados uno a uno, por tanto para eliminar todos los Documentos de una Colección, este no es el modo más eficiente. Para ello, existe la función drop()que se encarga de borrar una Colección entera, incluyendo todos sus Documentos y los Índices asociados. La función drop() no recibe ningún parámetro y en caso de pasar algún parámetro obtendremos un error.

db.posts.drop()

9. Lecturas recomendadas

Ya sabéis cualquier mejora, comentario, sugerencia, será bien recibido 😉

Anuncios
2 comentarios leave one →
  1. Marcos permalink
    5 junio 2013 11:45

    Muy buena intro 😉

Trackbacks

  1. MongoDB Certification Program | Rekkeb's Blog

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: