MongoDB, primeros pasos
Lo primero, os dejo el enlace a las: fuentes de este tutorial
Introducción
Estoy ahora mismo nadando en el nuevo océano de las bases de datos NoSQL, leyendo libros, probando cosas etc…
y necesitaba pasar un poco a la acción. Tengo un tutorial sin terminar de Apache CouchDB (que ya acabaré), donde hago un poco
de introducción más conceptual de estos temas, por eso ahora paso un poco de esta parte y voy directamente al grano.
Únicamente enumeraré algunas de las características de MongoDB:
- Base de datos orientada a documentos, es decir que no es relacional.
Podemos comparar más o menos el concepto de fila en SQL al de documento. También podemos comparar el concepto de colección
al de tabla y el de base de datos a esquema. - Fácilmente escalable. Básicamente, todo el diseño desde el principio está orientado a conseguir esto.
- Es indexable, incluso permite índices geoespaciales (para hacer búsquedas por cercanía geográfica y similares)
- Sustituye el concepto de procedimientos almacenados por funciones JavaScript.
- Permite colecciones de tamaño fijo que ofrecen una velocidad muy alta en acceso y modificación, ideales para información relacionada con trazas o por ejemplo cacheo.
- etc…
Instalando MongoDB
Lo primero será visitar la página de descargas de MongoDB.
Seleccionamos la versión adecuada, en mi caso Windows 32 bits:
Una vez descargado el fichero, debemos descomprimirlo en algún lugar del disco.
Bueno, pues ya lo hemos instalado. Fácil, como a mi me gusta.
Arrancando MongoDB
Es momento de arrancar una ventana de comandos y navegar al directorio «bin» de la instalación de mongo.
El ejecutable es «mongod.exe» . Por defecto, MongoDB usará «C:\data\db» como directorio de datos.
Si no existe os dará un error.
Ahora tenéis dos opciones: o creáis ese directorio, o creáis otro diferente y se lo indicáis en el arranque.
Yo elijo la segunda:
Si preferís instalarla como un servicio, entonces podéis ejecutar el siguiente comando: (adaptarlo a vuestro caso)
mongod.exe –logpath «D:\herramientas\mongodb-win32-i386-1.6.5\logs» –dbpath «D:\herramientas\mongodb-win32-i386-1.6.5\data» –install
A continuación, arrancamos el servicio tal y como nos indica:
Es un buen momento para visitar la consola de administración Web:
Hola Mundo en MongoDB
Vamos a empezar a guardar cosicas en la Base de Datos, que para eso sirve esto.
Lo primero, es configurar un proyecto en maven para usar Mongo (el driver):
4.0.0 testingMongo testingMongo 1.0-SNAPSHOT jar testingMongo http://maven.apache.org UTF-8 true maven-compiler-plugin 1.5 UTF-8 maven-resources-plugin UTF-8 junit junit 4.8 test org.mongodb mongo-java-driver 2.3
Como hoy estoy juguetón, voy a intentar poner en práctica algunas cosillas que vimos en el curso con Carlos Blé de APIs fluidas
y TDD que tanto me gustó, así jugamos con tres cosas, con el Mongo, con el TDD y con las APIs fluidas.
Voy a salvar mi primer documento en MongoDB y quiero hacerlo así:
... saveThis(myDocument) .onThisDataBase("misDatos") .inThisCollection("miColeccion").execute(); ...
Así que me hago mi test unitario que primero no compila, y luego no funciona, y luego sí funciona,
y luego sí funciona pero guardando cosas de verdad (a buen entendedor…)
Así queda el test unitario:
... import static com.autentia.tutoriales.mongo.Mongui.*; ... public class MongoTest { ... @Test public void saveSomeThingInMongoUsingMongui() { MonguiDocument myDocument = new MonguiDocument(); myDocument.put("saludo", "HolaMundo"); saveThis(myDocument) .onThisDataBase("misDatos") .inThisCollection("miColeccion").execute(); Mongo mongo = createMongo(); DB database = mongo.getDB("misDatos"); DBCollection coleccion = database.getCollection("miColeccion"); Assert.assertTrue(coleccion.getCount()>0); } ...
Podréis comprobar que no es necesario crear ni la base de datos, ni las colecciones. Si no existen, pues se crean automáticamente en la operación de guardar.
Además, veréis que no se impone ninguna restricción en el esquema de esa colección. Vamos en la colección puedo guardar peras,
churros, balones o lo que me dé la gana.
Bueno, jugando al TDD emerge un API al que he decidido llamar Mongui y en el que he intentado que el cliente no se acople con Mongo.
Hay algunos APIs que facilitan el trabajo con Mongo, aquí os dejo un enlace interesante al respecto.
Después, decido que quiero obtener todos los documentos de una colección y quiero hacerlo así:
obtainAll() .onThisDataBase("otrosDatos") .inThisCollection("otraColeccion").execute();
Repitiendo el proceso de antes:
... import static com.autentia.tutoriales.mongo.Mongui.*; ... public class MongoTest { ... @Test public void getSomeThingfromMongoUsingMongui() { Mongo mongo = createMongo(); DB database = mongo.getDB("otrosDatos"); DBCollection coleccion = database.getCollection("otraColeccion"); BasicDBObject object = new BasicDBObject("pipi", "kaka"); coleccion.save(object); DBCursor cursor = (DBCursor) obtainAll() .onThisDataBase("otrosDatos") .inThisCollection("otraColeccion").execute(); Assert.assertTrue(cursor.count()>0); } ... }
La clase Mongui ha quedado así:
package com.autentia.tutoriales.mongo; public abstract class Mongui { MonguiDataConnection connection; MonguiCollection actualCollection; MonguiDataBase actualDataBase; Mongui() throws MonguiException { try { this.connection = new MonguiDataConnection(); } catch (Exception e) { treatError(e); } } private void treatError(Exception e) throws MonguiException { throw new MonguiException("Problem creating Connection to Mongo", e); } public final Mongui inThisCollection(String collectionName) { this.actualCollection = new MonguiCollection(actualDataBase,collectionName); return this; } public final Mongui onThisDataBase(String dataBaseName) { this.actualDataBase = new MonguiDataBase(connection,dataBaseName); return this; } public abstract Object execute(); public static Mongui saveThis(MonguiDocument myDocument) { return new MonguiSaver(myDocument); } public static Mongui obtainAll() { return new MonguiGetter(); } }
La clase MonguiSaver:
package com.autentia.tutoriales.mongo; public class MonguiSaver extends Mongui { private MonguiDocument actualDocument; MonguiSaver(MonguiDocument actualDocument) { super(); this.actualDocument = actualDocument; } @Override public Object execute() { actualCollection.saveDocument(actualDocument); return null; } }
La clase MonguiGetter:
package com.autentia.tutoriales.mongo; public class MonguiGetter extends Mongui { MonguiGetter() throws MonguiException { super(); } @Override public Object execute() { return actualCollection.getAll(); } }
Las demás clases no son más que wrappers sobre las clases reales del driver de Mongo y que podéis ver en el código fuente.
La shell
Una vez que ya hemos guardado algunas cosillas con el driver java, podemos probar la shell javascript de Mongo:
Abrid una ventana de comandos, y en el directorio «bin» de Mongo, ejecutad «mongo.exe»
Cambiemos a alguna de las bases de datos que hemos creado durante los tests. Escribid «use otrosDatos» por ejemplo:
Vamos a ver qué colecciones tiene esta base de datos: Escribid «db.getCollectionNames()»:
Parece que esto va. Vamos a ver que tiene la colección: Escribid «db.otraColeccion.find()»
Bueno, pues ahora vamos a insertar en la misma colección otra cosa diferente, acordáos que esto es JavaScript:
Ahora volvemos a buscar:
Aprovechando que está aquí Ivan le enseño esto con otro ejemplo:
Vamos a ver un resumen del estado de la base de datos:
Y como no todo es jugar, sino que también hay que trabajar, paramos mongo:
Conclusiones
La verdad que ha sido bastante fácil empezar con esto y tiene muy buena pinta. Lo de la consola JavaScript es un puntazo
(me he tenido que obligar a mi mismo a dejarlo).
Seguiremos jugando, para probar otros temas más relacionados con su facilidad para escalar, sharding y demás historias.
Interesante….
Paco, ¿está es la BD que usa Twitter y las redes sociales tengo entendido, ¿no? Saludos,