Bueno como he ido comentando en los posts de Node empezamos con MongoDB aunque dentro de poco lo juntaremos con Node para trabajar. Comentar que no todo el contenido es propiamente mio, está todo basado en conocimientos transmitidos por KeepCoding y en Webinars oficiales de MongoDB, mezclado con mi experiencia personal ;)

¿Qué es MongoDB?

MongoDB es una base de datos no relacional sin esquemas.....y esto que significa:

  • No tenemos JOIN, tendremos que hacerlo nosotros
  • Cada registro podría tener una estructura distinta
  • Mínimo soporte a transacciones
  • Como su nombre indica no se basa en las relaciones entre sus elementos.

Una base de datos NoSql(el termino por cierto vino de un hastag de twitter no es realmente oficial #nosql) puede darnos bastante más rendimiento que una relacional (según en que entorno por supuesto) por algunas razones como estas:

  • No tiene que gestionar transacciones
  • No tiene que gestionar relaciones
  • No es necesario convertir objetos a tablas y tablas a objetos....

Definen su propia arquitectura como Nexus, porque no es una NoSql típica, cumple con los básicos de una base de datos no relacional:

  • Flexibilidad: Soporta casi de todos los tipos de elementos que queramos.
  • Escalabilidad y rendimiento: Podemos aumentar el número de servidores de base de datos hasta que nos cansemos (todos ellos trabajando en la misma) y el rendimiento aumentaría casi de forma lineal (esa es la teoría).
  • Siempre disponible y despliegue global: Viene muy relacionado con el punto anterior, porque tener muchos servidores nos garantiza disponibilidad, y esos mismos servidores pueden estar distribuidos por todo el mundo.

Pero además de cumplir como NoSql tiene características que la hacen ser algo más (al estilo relacional):

  • Lenguaje de querys muy expresivo: Podemos crear querys casi tan complejas como en un lenguaje relacional.
  • Indices secundarios: Tras usar un indice principal para una búsqueda, si previamente lo hemos configurado usaría otro secundario (pensando en querys complejas donde se vayan cumpliendo cosas) lo que hace que la busqueda sea muy agil.
  • Fuerte consistencia
  • Enterprise Management & Integrations: Esta pensada para trabajar casi en cualquier entorno, con múltiples sistemas de integración y con gestión empresarial.

Podemos comentar también que no tiene esquema definido, toda la responsabilidad del orden de los datos la tiene la aplicación que use la base de datos, es decir, si queremos de repente tener un campo nuevo solo tenemos que hacerlo directamente en nuestro código Java, JavaScript,etc.... y MongoDB lo aceptará.

No voy a entrar en temas de escalabilidad y tolerancia a fallos muy a fondo, solo comentar que:

  • Tenemos escalabilidad podríamos decir vertical, lo que se conocería como Replica Set, serían varios servidores juntos en los que tenemos uno primaria y otros secundarios que van compartiendo información, cuando uno falla en unos 2 segundos se levantará uno de los secundarios. Por lo que realmente cualquiera puede ser primario o secundario.
  • Y también tenemos escalabilidad horizontal, conocida como shards, cada shard es un conjunto de replica set normalmente separados geográficamente o por lo menos no están agrupados como sería con los replica set. Dentro de este entorno podemos definir que se replica y donde, por ejemplo por temas de la LOPD solo queremos que los datos de España se repliquen en servidores que esten en España. Y para controlar que querys van a que servidor tenemos un proceso llamado MongoS (Mongo Shard Router), que normalmente existe uno por servidor, que es el que se encargaría de dirigir estas querys a su lugar correcto.

Creo que hasta aquí tenemos lo básico sobre Mongo, continuemos con la instalación.

Instalación

Más que instalación yo diría que es descarga y ejecución pero bueno mantengamos el orden un poco :P.
Tenemos varias opciones, definidas también según nuestro sistema operativo: Linux, Windows o MacOS.
En general es bastante sencillo, se instala/descarga y se ejecuta definiendo el path donde se guardará nuestra base de datos, en mi caso trabajo en el blog con MacOS asi que los ejemplos pueden estar un poco más enfocados a este sistema operativo pero intentaré ser lo más genérico posible.
Una vez instalado y ejecutado (cada uno que situe la base de datos donde quiera tal como lo pone en la documentación de instalación) por defecto estará esperando conexiones en el puerto 27017, pero se podría cambiar por cualquier otro sin problema.
En windows se gestiona su arranque y detenimiento con comandos específicos que vienen en la documentación, en el caso de linux y mac, si lo hemos realizado descargando e instalando tendremos un shell que es donde veremos los logs de consola que muestra mongo, para pararlo solo tenemos que cerrar la ventana o parar el proceso como cualquier otro.
Bien, una vez ejecutado, para trabajar de primeras con Mongo nos vamos a la carpeta donde tengamos descargado Mongo y dentro y podemos ejecutar

bin/mongo

Esto nos abrirá una conexión en shell con la base de datos
MongoDb Connect example

Y esto sería lo que muestra el log de consola de Mongo
Connection log example

Una vez conectados, veamos algunos comandos básicos de uso de MongoDB.

  • show dbs: Nos muestra las bases de datos que tenemos actualmente.

show dbs example

  • use nameDB: Para hacer gestiones en una base de datos específica. Esto también lo usaríamos para crear bases de datos nuevas (OJO hasta que no introduzcamos datos no nos aparecería)

use dbName example
Create new db

  • show collections: Muestra las colecciones existentes en esa base de datos (para haceros una idea serían algo así como las tablas en bases de datos relacionales)

show collections example
Si la base de datos es nueva de primeras no habría nada, las colecciones se crearián cuando insertemos algo (al igual que cualquier base de datos nueva), entonces vamos a insertar algo. Los datos en Mongo tienen un estilo similar json, al estilo clave => valor

db.heros.insert({name: "Batman", powers: "Money"})

Al insertar algo correctamente la consola nos lo indicaría

Document inserted

Una vez insertado si ahora hacemos un show dbs nos mostraría la nueva base de datos, y lo mismo al hacer show collections tras seleccionar esa base de datos

Show new collections

  • Ver lo que tiene una colección: Para ver lo que tiene una colección lo hacemos con db.collectionName.find(), es decir:
db.heros.find()

También podemos ponerle .pretty() al final para que nos lo muestre en un formato quizá más cómodo si tenemos varios objetos

Find documents example

Si os fijáis tenemos una nueva propiedad en nuestro objeto que es _id, esta propiedad es un identificador único de objeto que le asigna Mongo por defecto a cada elemtento insertado. Vamos a crear alguno más para probar a borrar y actualizar alguno

db.heros.insert({name: "Superman", powers: "is Super, no more"})
db.heros.insert({name: "Goku", powers: "Super Saiyan"})

Si ahora hacemos un find

Find with more documents

Ya tenemos varios documentos, ahora vamos a eliminar alguno para probar, por ejemplo borremos a Superman. Os podéis imaginar pero veamos

  • Eliminar un elemento: Lo hacemos de manera similar al insert con db.colectionName.remove(idObject)
db.heros.remove({_id: ObjectId("59e1e758c5662c1d57baf70f")})

Esto nos indica que ha eliminado un elemento y si hacemos un find de nuevo tenemos solo dos elementos

Remove one item

  • Actualizar un elemento: Sigue la misma teoria que el resto, pero en este caso, a parte del criterio de búsqueda del objeto tenemos que indicarle también que es lo que actualizamos. En este caso en lugar de usar el id para encontrar un objeto lo haremos con otra propiedad, por ejemplo el nombre
db.heros.update({name: "Batman"}, {$set: {powers: "Ninjitsu"}})

OJO con $set, si no lo ponemos así nos sustituiría todo el elemento por lo que le hubieramos pasado.

Tras ejecutarlo, como siempre, la consola nos indica lo que ha hecho y si buscamos a Batman veremos como ha cambiado su propiedad powers

Batman powers update

  • Crear indices: Si vamos a buscar mucho por cierta propiedad en nuestros documentos dentro de mongo lo ideal es crear indices, ya que agilizan las búsquedas bastante, sobre todo cuando tenemos muchos elementos. Para ello es tan fácil como createIndex y dentro el orden del índice.
db.heros.createIndex({name: 1, powers: -1})

En este índice lo que le hemos puesto es que cree un índice primero por name con orden ascendente y eso mismo si el nombre es el mismo que lo ordene por la propiedad powers de forma descendente (creo que el +1 -1 está más o menos claro). Si queremos ver los índices que tenemos creados solo tenemos que hacer getIndexes()

db.heros.getIndexes()

Y nos devolverá algo como esto

Index examples

Como véis ya existia un índice ascendente por _id y luego esta el nuestro que acabamos de crear. Podemos ver más opciones con los índices en la documentación oficial

  • Eliminar una colección entera: Fácil db.colectionName.drop()
db.ninjas.drop()

Al no tener ninguna tabla más o colección nos eliminará también la base de datos

Captura-de-pantalla-2017-10-14-a-las-13.25.34

De momento lo vamos a dejar con la base de datos eliminada en el próximo post la crearemos de nuevo con otros elementos.

Estas serían las opciones más básicas, como tal en la documentación oficial tenemos muchas más.

Un abrazoooorrrr