MongoDB: la BBDD NoSQL más popular del mercado

7,882 views

Published on

Introducción a las bases de datos NoSQL
Concepto y campos relacionados
Principales características
Arquitectura de las bases de datos NoSQL
Taxonomía de soluciones NoSQL
Empresas que usan bases de datos NoSQL
MongoDB: una BBDD NoSQL orientada a Documentos
Introducción: características y arquitectura
Instalación sobre diferentes sistemas operativos
Utilidades de mongoDB: mongo, mongostat, mongotop, etc.
Características principales:
Consultas Ad hoc
Indexación
Replicación
Balanceo de carga
Almacenamiento de archivos
Agregación
Programación en MongoDB
Ejecución de JavaScript del lado del servidor
Programación de MongoDB desde Java y Python
Desarrollo de una aplicación avanzada con MongoDB
Conclusiones
Otras alternativas destacables: CouchDB
Aplicabilidad a mi empresa

Published in: Technology
1 Comment
22 Likes
Statistics
Notes
No Downloads
Views
Total views
7,882
On SlideShare
0
From Embeds
0
Number of Embeds
21
Actions
Shares
0
Downloads
364
Comments
1
Likes
22
Embeds 0
No embeds

No notes for slide

MongoDB: la BBDD NoSQL más popular del mercado

  1. 1. 1 MongoDB: la BBDD NoSQL más popular del mercado 21 Mayo de 2014, 9:00-14:00 Parque Tecnológico de Zamudio. Edificio Tecnalia, #204, Bizkaia Dr. Diego López-de-Ipiña González-de-Artaza dipina@deusto.es http://paginaspersonales.deusto.es/dipina http://www.slideshare.net/dipina Apuntes + Ejemplos + Docs + Downloads disponibles en: https://www.dropbox.com/sh/yz51jkr9y6t3c51/iXm679-WvJ/MongoDB
  2. 2. 2 Agenda 1. Introducción a las bases de datos NoSQL a. Concepto y campos relacionados b. Principales características c. Arquitectura de las bases de datos NoSQL d. Taxonomía de soluciones NoSQL e. Empresas que usan bases de datos NoSQL 2. MongoDB: una BBDD NoSQL orientada a Documentos a. Introducción: características y arquitectura b. Instalación sobre diferentes sistemas operativos c. Utilidades de mongoDB: mongo, mongostat, mongotop, etc. d. Características principales: • Consultas Ad hoc • Indexación • Replicación • Balanceo de carga • Almacenamiento de archivos • Agregación
  3. 3. 3 Agenda Descanso 3. Programación en MongoDB a. Ejecución de JavaScript del lado del servidor b. Programación de MongoDB desde Java y Python c. Desarrollo de una aplicación avanzada con MongoDB 4. Conclusiones a. Otras alternativas destacables: CouchDB b. Aplicabilidad a mi empresa
  4. 4. 4 Introducción a NoSQL • NoSQL propone que la capa de persistencia no es necesariamente la responsabilidad de un único sistema – Mientras que los proveedores de bases de datos relacionales han pretendido vender su producto como una solución única a todos los problemas … • NoSQL propone que la mejor herramienta de almacenamiento para cada propósito sea utilizada – NoSQL supone estar abierto y ser consciente de alternativas, existentes y patrones adicionales y herramientas para gestionar tus datos. • MongoDB debería ser visto como una alternativa a las bases de datos relacionales
  5. 5. 5 Introducción a NoSQL • NoSQL – "not only SQL” – es una categoría general de sistemas de gestión de bases de datos que difiere de los RDBMS en diferente modos: – No tienen schemas, no permiten JOINs, no intentan garantizar ACID y escalan horizontalmente – Tanto las bases de datos NoSQL como las relacionales son tipos de Almacenamiento Estructurado. • El término fue acuñado en 1998 por Carlo Strozzi y resucitado en 2009 por Eric Evans – Evans sugiere mejor referirse a esta familia de BBDD de nueva generación como “Big Data” mientras que Strozzi considera ahora que NoREL es un mejor nombre
  6. 6. 6 Introducción a NoSQL • La principal diferencia radica en cómo guardan los datos (por ejemplo, almacenamiento de un recibo): – En una RDBMS tendríamos que partir la información en diferentes tablas y luego usar un lenguaje de programación en la parte servidora para transformar estos datos en objetos de la vida real. – En NoSQL, simplemente guardas el recibo: • NoSQL es libre de schemas, tú no diseñas tus tablas y su estructura por adelantado • ¡¡¡NoSQL no es la panacea!!! – Si tus datos son relacionales, quedarte con tu RDBMS sería generalmente la opción correcta … • Aunque MongoDB siempre puede ser una alternativa!
  7. 7. 7 Características principales • Fáciles de usar en clústers de balanceo de carga convencionales  facilitan escalabilidad horizontal • Guardan datos persistentes (no sólo cachés) • No tienen esquemas fijos y permite la migración del esquema sin tener que ser reiniciadas o paradas • Suelen tener un sistema de consultas propio en vez de usar un lenguaje de consultas estándar • Tienen propiedades ACID en un nodo del clúster y son “eventualmente consistentes” en el clúster
  8. 8. 8 El teorema CAP • Teorema de Brewer: “es imposible para un sistema computacional distribuido ofrecer simultáneamente las siguientes tres garantías”: – Consistencia – todos los nodos ven los mismos datos al mismo tiempo – Disponibilidad (Availability) – garantiza que cada petición recibe una respuesta acerca de si tuvo éxito o no – Tolerancia a la partición (Partition) – el sistema continua funcionando a pesar de la pérdida de mensajes • Equivalente a: – “You can have it good, you can have it fast, you can have it cheap: pick two.”
  9. 9. 9 ACID vs. BASE • En el mundo relacional estamos familiarizados con las transacciones ACID, que garantizar la consistencia y estabilidad de las operaciones pero requieren lockings sofisticados: – ACID = Atomicidad, Consistencia, (Isolation) aislamiento y Durabilidad • Las BBDD NoSQL son repositorios de almacenamiento más optimistas , siguen el modelo BASE: – BAsic availability – el almacén funciona la mayoría del tiempo incluso ante fallos gracias al almacenamiento distribuido y replicado – Soft-state – los almacenes no tienen porque ser consistentes ni sus réplicas en todo momento. El programador puede verificar esa consistencia. – Eventual consistency – la consistencia se da eventualmente • BASE es una alternativa flexible a ACID para aquellos almacenes de datos que no requieren un adherencia estricta al modelo relacional.
  10. 10. 10 RDBMS vs. NoSQL • Los RDBMS tradicionales nos permiten definir la estructura de un esquema que demanda reglas rígidas y garantizan ACID • Las aplicaciones web modernas presentan desafíos muy distintos a las que presentan los sistemas empresariales tradicionales (e.j. sistemas bancarios): – Datos a escala web – Alta frecuencia de lecturas y escrituras – Cambios de esquema de datos frecuentes – Las aplicaciones sociales (no bancarias) no necesitan el mismo nivel de ACID • Algunas de las opciones de NoSQL actualmente disponibles son: – MongoDB, Cassandra, Jackrabbit , CouchDB, BigTable, Dynamo o Neo4j
  11. 11. 11 ¿Por qué necesitas NoSQL? • Desafíos en tu sistema de información que son difíciles de resolver usando tecnología de bases de datos relacionales: – Tu BBDD no escala a tu tráfico a un coste aceptable – El tamaño de tu esquema de datos ha crecido desproporcionalmente. – Tu sistema de información genera mucho datos temporales que no corresponden al almacén de datos principal (carritos de compra, personalización de portales) – Tu BBDD ha sido desnormalizada por razones de rendimiento o por conveniencia para utilizar los datos en una aplicación – Tu dataset tiene grandes cantidades de texto o imágenes y la columnas como BLOBs – Ejecutas consultas contra datos que no implican relaciones jerárquicas sencillas; recomendaciones o consultas de inteligencia de negocio. Ejemplo: "all people in a social network who have not purchased a book this year who are once removed from people who have“ – Usas transacciones locales que no necesitan ser muy durables, e.j. Like. • Los sites AJAX tienen muchos casos de uso de este estilo.
  12. 12. 12 Arquitectura de las BBDD NoSQL • A menudo ofrecen sólo garantías de consistencia débiles, como por ejemplo eventual consistency, o transacciones restringidas a elementos de datos simples • Emplean una arquitectura distribuida, donde los datos se guardan de modo redundante en distintos servidores, a menudo usando tablas hash distribuidas • Suelen ofrecer estructuras de datos sencillas como arrays asociativos o almacenes de pares clave-valor
  13. 13. 13 ¿Qué tipo de BBDD elijo? • Algunas respuestas pueden encontrarse en: – 35+ Use Cases For Choosing Your Next NoSQL Database • http://highscalability.com/blog/2011/6/20 /35-use-cases-for-choosing-your-next- nosql-database.html – Five Reasons to Use NoSQL • http://facility9.com/2010/09/five-reasons- to-use-nosql/ – Which freaking database should I use? • http://www.infoworld.com/print/199184
  14. 14. 14 DB-Engines Ranking
  15. 15. 15 Soluciones Empresariales NoSQL • BigTable (column oriented) es un sistema de gestión de base de datos creado por Google distribuido, de alta eficiencia y propietario. – Google Cloud Datastore (App Engine NoSQL Data Storage) motor de BBDD NoSQL factorizado de Google App Engine • BBDD de columnas que soporta transacciones ACID, tiene alta disponibilidad a través de centros de replicación y consultas SQL-like • Amazon DynamoDB (row oriented) es un servicio de bases de datos NoSQL rápido y totalmente gestionado que permite almacenar y recuperar de manera fácil y económica cualquier cantidad de datos y atender cualquier nivel de tráfico • Comparativa: – http://www.theregister.co.uk/2013/05/16/google_datastore/
  16. 16. 16 Conceptos asociados a BBDD distribuidas • Almacenes basados en columnas y filas. RDBMS almacenan las filas de modo continuo en disco, mientras que algunas NoSQL guardan así las columnas • Consistencia eventual: si no se realizan nuevas actualizaciones a un elemento de datos, todos los accesos del elemento devolverán el último valor actualizado • Sharding: es una partición horizontal en una BBDD donde las filas de una tabla se mantienen de modo separado • Replicación maestro-maestro es un método de replicación de BBDD que permite almacenar datos en un grupo de nodos y su actualización por cualquier miembro del grupo • Replicación maestro-esclavo donde un sólo elemento se designa como “maestro” de un datastore y es el único nodo que permite modificar datos • Particionado es la división de una BBDD lógica y sus partes constituyentes en un conjunto de partes independientes. • Modelo de consistencia: contrato entre el programador y el sistema sobre las garantías de consistencia (write & read consistency: one, all, quorum, etc.)
  17. 17. 17 Taxonomía de soluciones NoSQL • Los principales tipos de BBDD de acuerdo con su implementación son los siguientes: – Almacenes de Clave-Valor – Almacenes de documentos – Grafos
  18. 18. 18 BBDD orientadas a Clave-Valor • Su precursor fue Google BigTable • Modelo de datos: familia de columnas, esto es, un modelo tabular donde cada fila puede tener una configuración diferente de columnas • Ejemplos: HBase, Hypertable, Cassandra, Riak • Buenas en: – Gestión de tamaño – Cargas de escrituras masivas orientas al stream – Alta disponibilidad – MapReduce
  19. 19. 19 BBDD orientadas a Documentos • La precursora fue Lotus Notes • Modelo de datos: colecciones de documentos (JSON, XML, BSON) que contienen colecciones de claves-valor • Ejemplos: CouchDB, MongoDB • Buenas en: – Modelado de datos natural – Amigables al programador – Desarrollo rápido – Orientas a la web: CRUD
  20. 20. 20 BBDD orientadas a Grafos • Modelo de datos: grafo de propiedades formado por las entidades nodos, relaciones y propiedades tanto de nodos como relaciones • Ejemplos: Neo4j • Buenas en: – Modelar directamente un dominio en forma de grafo, una manera común de representar y entender datasets – Ofrecer excelente rendimiento cuando los datos están interconectados y no tabulares – Realizar operaciones transaccionales que exploten las relaciones entre entidades
  21. 21. 21 El teorema de CAP
  22. 22. 22 Persistencia Políglota • Toda empresa va a acabar teniendo una variedad de tecnologías de almacenamiento para diferentes tipos de datos – El código de nuestros sistemas va a tener acceso a diferentes repositorios de datos – Muchos datos seguirán guardándose en almacenes relacionales pero debemos empezar a preguntarnos cómo queremos utilizar los datos y sólo entonces decidir qué tecnología es mejor • Usar NoSQL para una característica particular de una aplicación – Rápido procesado batch – Logging distribuido – Para grandes tablas • Usar una RDBMS para reporting – Se complica la lógica de la aplicación y el despliegue – Responsabilidades administrativas adicionales • Hay que ¡elegir la herramienta adecuada para cada trabajo!
  23. 23. 23 Persistencia Políglota
  24. 24. 24 MongoDB • Similar a CouchDB • Pretende combinar lo mejor de los almacenes clave/valor, bases de datos de documentos y RDBMS • Hace uso de JSON y tiene su propio lenguaje de consultas • Implementada en C++ • Usada por SourceForge, Bit.ly, Foursquare o GitHub • URL: http://www.mongodb.org/
  25. 25. 25 • MongoDB (de la palabra en ingles “humongous” que significa enorme) es un sistema de base de datos NoSQL orientado a documentos – MongoDB guarda estructuras de datos en documentos tipo BSON (Binary JSON (JSON Binario) con un esquema dinámico , haciendo que la integración de los datos en ciertas aplicaciones sea mas fácil y rápida. • Lo que MongoDB no puede hacer: • No hay tablas de BBDD • No hay “joins” • No hay transacciones • Y MongoDB no usa esquemas de datos
  26. 26. 26 Características Principales • Modelo de datos basado en documentos – Frente al modelo de datos relacional • Consultas ad hoc • Índices secundarios • Replicación • Velocidad y durabilidad • Escalabilidad
  27. 27. 27 Características Principales • Consultas Ad hoc – MongoDB soporta la búsqueda por campos, consultas de rangos y expresiones regulares. – Las consultas pueden devolver un campo específico del documento pero también puede ser una función JavaScript definida por el usuario. • Indexación – Cualquier campo en un documento de MongoDB puede ser indexado, al igual que es posible hacer índices secundarios. • El concepto de índices en MongoDB es similar a los encontrados en base de datos relacionales. • Replicación – MongoDB soporta el tipo de replicación maestro-esclavo. • El maestro puede ejecutar comandos de lectura y escritura. • El esclavo puede copiar los datos del maestro y sólo se puede usar para lectura o para copia de seguridad, pero no se pueden realizar escrituras. – El esclavo tiene la habilidad de poder elegir un nuevo maestro en caso del que se caiga el servicio con el maestro actual.
  28. 28. 28 Características Principales • Balanceo de carga – MongoDB se puede escalar de forma horizontal usando el concepto de “shard”. – El desarrollador elije una llave shard, la cual determina cómo serán distribuidos los datos en una colección. Los datos son divididos en rangos (basado en la llave shard) y distribuidos a través de múltiples shard. – Un shard es un maestro con uno o más esclavos. – MongoDB tiene la capacidad de ejecutarse en múltiple servidores, balanceando la carga y/o duplicando los datos para poder mantener el sistema funcionando en caso que exista un fallo de hardware. • Almacenamiento de archivos – MongoDB puede ser utilizado con un sistema de archivos, tomando la ventaja de la capacidad que tiene MongoDB para el balanceo de carga y la replicación de datos utilizando múltiples servidores para el almacenamiento de archivos. – Esta función (que es llamada GridFS ) está incluida en los drivers de MongoDB y disponible para los lenguajes de programación que soporta MongoDB. • Agregación – La función MapReduce y el operador aggregate() puede ser utilizada para el procesamiento por lotes de datos y operaciones de agregación. – Estos mecanismos permiten que los usuarios puedan obtener el tipo de resultado que se obtiene cuando se utiliza el comando SQL “group-by”. • Ejecución de JavaScript del lado del servidor – MongoDB tiene la capacidad de realizar consultas utilizando JavaScript, haciendo que estas sean enviadas directamente a la base de datos para ser ejecutadas: db.system.js.save • http://docs.mongodb.org/manual/tutorial/store-javascript-function-on-server/
  29. 29. 29 Casos de uso de MongoDB • Almacenamiento y registro de eventos • Para sistemas de manejo de documentos y contenido • Comercio Electrónico • Juegos • Problemas de alto volumen • Aplicaciones móviles • Almacén de datos operacional de una página Web • Manejo de contenido • Almacenamiento de comentarios – Votaciones – Registro de usarios – Perfiles de usuarios – Sesiones de datos • Proyectos que utilizan metodologías de desarrollo iterativo o ágiles • Manejo de estadísticas en tiempo real
  30. 30. 30 ¿Cuándo usar MongoDB? • MongoDB puede ser utilizado como una alternativa directa a las bases de datos relacionales • Importante considerarlo como una alternativa en vez de un remplazo – Puede hacer muchas cosas que otras herramientas pueden hacer – Algunas cosas las hace mejor y otras peor • Aunque no usar esquemas puede ser cómodo y ágil, casi todos los datos son estructurados – El beneficio real es no tener que crear las estructuras de datos antes de usarlas y reducir el cisma entre OOP y datos
  31. 31. 31 Manipulación de Datos: colecciones y documentos • MongoDB guarda la estructura de los datos en documentos tipo JSON con un esquema dinámico llamado BSON, lo que implica que no existe un esquema predefinido. • Los elementos de los datos son llamados documentos y se guardan en colecciones • Una colección puede tener un número indeterminado de documentos – Las colecciones son como tablas y los documentos como filas – Cada documento en una colección puede tener diferentes campos. • La estructura de un documento es simple y compuesta por “key-value pairs” parecido a las matrices asociativas en un lenguaje de programación – Como valor se pueden usar números, cadenas o datos binarios como imágenes o cualquier otro “key-value pairs”.
  32. 32. 32 6 Conceptos Clave 1. MongoDB tiene el concepto de “base de datos” con el que estamos familiarizados (schema en el mundo relacional). – Dentro de un servidor MongoDB podemos tener 0 o más BBDD, cada una actuando como un contenedor de todo lo demás. 2. Una base de datos puede tener una o más “colecciones”, equivalente en el mundo relacional a una “tabla”. 3. Las colecciones están hechas de 0 o más “documentos”, donde un documento puede considerarse equivalente a una fila de una tabla de un RDBMS. 4. Un documento está compuesto de uno o varios “campos” que son equivalentes a las columnas de una fila. 5. Los “índices” en MongoDB funcionan como los de las RDBMS. 6. Los “cursores” son utilizados para acceder progresivamente a los datos recuperados con una consulta – Pueden usarse para contar o moverse hacia delante entre los datos
  33. 33. 33 Ejemplo de documento en MongoDB { "_id": ObjectId("4efa8d2b7d284dad101e4bc7"), "Last Name": "PELLERIN", "First Name": "Franck", "Age": 29, "Address": { "Street": "1 chemin des Loges", "City": "VERSAILLES" } }
  34. 34. 34 BSON • BSON versión binaria de JSON, serialización codificada en binario de documentos JSON – Soporta colocar documentos dentro de un documento y arrays dentro de otros documentos y arrays – Contiene extensiones que permiten representar tipos de datos que no son parte de JSON • Por ejemplo, BSON tiene los tipos de datos Date y BinData • BSON soporta los siguientes tipos de datos numéricos: – int32 - 4 bytes (enteros con signo de 32-bit) – int64 - 8 bytes (enteros con signo de 64-bit) – double - 8 bytes (64-bit IEEE 754 de coma flotante) • Documentación en: http://bsonspec.org/
  35. 35. 35 Claves de los documentos • Además de los datos de un documento, MongoDB siempre introduce un campo adicional _id – Todo documento tiene que tener un campo _id único – Este campo _id puede contener un valor de cualquier tipo BSON, excepto un array • Más info en http://docs.mongodb.org/manual/core/document/ • Podemos generar el identificador nosotros: – x = "55674321R" – y = ObjectId("507f191e810c19729de860ea") • o dejarle a MongoDB que lo haga – Entonces el tipo de ese campo es ObjectId: http://docs.mongodb.org/manual/reference/object-id/ • Es un tipo de datos de 12 bytes, donde 4 bytes representan un timestamp, 3 un identificador de máquina, 2 el identificador del proceso y 3 restantes un contador – Tiene el atributo str y los métodos getTimeStamp() y toString() – Es preferible que MongoDB lo genere por nosotros • El campo _id es indexado lo que explica que se guardan sus detalles en la colección del sistema system.indexes
  36. 36. 36 Utilidades de MongoDB • Los siguientes comandos pueden ser instalados para el manejo y la administración del sistema de base de datos: – mongo: es un Shell interactivo que permite a los desarrolladores ver, insertar, eliminar y actualizar datos en su base de datos. Este también permite entre otras funciones la replicación de información, configurar los Shards, apagar los servidores y ejecutar JavaScript. – mongostat: es una herramienta de línea de comandos que muestra en resumen una lista de estadísticas de una instancia de MongoDB en ejecución. – mongotop: es una herramienta de línea de comandos que provee un método para dar seguimiento a la cantidad de tiempo que dura una la lectura o escritura de datos en una instancia. – mongosniff: es una herramienta de línea de comandos que provee un sniffing en la base de datos haciendo un sniffing en el tráfico de la red que va desde y hacia MongoDB. – mongoimport/mongoexport: es una herramienta de línea de comandos que facilita la importación exportación de contenido desde JSON, CSV o TSV. – mongodump/mongorestore: es una herramienta de línea de comandos para la creación de una exportación binaria del contenido de la base de datos.
  37. 37. 37 Documentación e instalación • La documentación completa de MongoDB puede encontrarse en: – http://docs.mongodb.org/manual/ • Instrucciones para instalar MongoDB en Windows: – Descargar la última versión de: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-windows/ – Crear directorio de datos: mkdir datadb – Ejecutar el comando: mongod.exe --dbpath datadb – Ejecutar: mongod --config mongod.config • Habiendo creado previamente el fichero mongod.config: dbpath=PATH_TO_WHERE_YOU_WANT_TO_STORE_YOUR_DATABASE – Ejecutar el cliente mongo y los siguientes comandos en JavaScript: %INSTALL_DIR%mongodb-win32-x86_64-2.4.5bin>mongo MongoDB shell version: 2.4.5 connecting to: test > db.test.save( {a:1} ) > db.test.find() { "_id" : ObjectId("4fe6e41b184d3a26629be9b6"), "a" : 1 } >
  38. 38. 38 Más sobre instalación en MongoDB • El siguiente enlace contiene más detalles sobre la instalación de MongoDB: – http://www.mkyong.com/tutorials/java-mongodb-tutorials/ • Instrucciones para instalar MongoDB en Windows: – Descargar la última versión (2.6.1) para tu plataforma de: • http://www.mongodb.org/downloads – Revisa el directorio de MongoDB que contendrá 10 ejecutables en la carpeta bin – Se puede crear un fichero con las opciones de configuración por defecto de MongoDB: mongo.config dbpath=D:mongodbdata #all output go here logpath=D:mongodblogmongo.log #log read and write operations diaglog=3 – Ejecuta el servidor: mongod --config mongo.config – Conectarse el servidor con el cliente: mongo
  39. 39. 39 Usando MongoDB • mongo es un shell JavaScript completo, cualquier función JavaScript, sintaxis o clase puede usarse en el shell > j = { name : "mongo" }; { "name" : "mongo" } > t = { x : 3 }; { "x" : 3 } > db.things.save(j); > db.things.save(t); > db.things.find(); { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d90"), "name" : "mongo" } { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d91"), "x" : 3 } > for (var i = 1; i <= 20; i++) db.things.save({x : 4, j : i}); > db.things.find(); { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d90"), "name" : "mongo" } { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d91"), "x" : 3 } ... Type "it" for more > // Iterate through the remaining items > it { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8da4"), "x" : 4, "j" : 19 } { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8da5"), "x" : 4, "j" : 20 }
  40. 40. 40 Usando MongoDB > // Store the cursor of the DB in a variable > var cursor = db.things.find(); > while (cursor.hasNext()) printjson(cursor.next()); { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d90"), "name" : "mongo" } { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d91"), "x" : 3 } ... > // Use functional features of JavaScript > db.things.find().forEach(printjson); { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d90"), "name" : "mongo" } { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d91"), "x" : 3 } ... > // cursors like an array > var cursor = db.things.find(); > printjson(cursor[4]); { "_id" : ObjectId("51e50d3b70f9b7c7fdbd8d94"), "x" : 4, "j" : 3 } >
  41. 41. 41 Mongo Shell • El shell Mongo se comporta como un buen shell de UNIX: – Ofrece autocompletado (usando el tabulador) – Te permite moverte por la historia de comandos con el cursor para arriba o abajo o moverte al primer o último comando con las combinaciones de teclas (CTRL-a y CTRL-e). – Ofrece un objeto implícito llamado db que representa a la base de datos • Si no se selecciona explícitamente una BBDD con el comando use <database-name>, se conecta por defecto a test – Las colecciones se crean automáticamente cuando insertamos el primer documento en ellas – Es un shell en JavaScript que no distingue entre enteros y números en coma flotante, todo número se representa en JavaScript como un número de coma flotante de 64 bits • Comandos útiles: – help – muestra ayuda – db.help()– muestra ayuda de los métodos de la BBDD – db.<collection>.help() – detalla qué métodos se pueden aplicar a una colección – show dbs – imprime una lista de las bases de datos del servidor – use <database-name>– cambia la base de datos a <db>, haciendo que db apunte la BBDD seleccionada – show collections – imprime todas las colecciones de la base de datos actual – show users – imprime los usuarios de la BBDD
  42. 42. 42 Mongo Shell • Operaciones administrativas: – db.cloneDatabase(<host>) – clona la base de datos del host especificado – db.copyDatabase(<from>, <to>, <host>) – copia de la BBDD <from> del <host> a la base de datos <to> del servidor actual • La instancia de base de datos <host> debe estar en modo noauth. – db.fromColl.renameCollection(<toColl>)– renombra la colección de fromColl a toColl – db.repairDatabase() – repara y compacta la base de datos actual • Esta operación puede ser muy lenta en bases de datos grandes – db.addUser( <user>, <pwd> ) – añade un usuario a la BBDD actual – db.getCollectionNames()– obtiene la lista de colecciones de la base de datos actual – db.dropDatabase() – borra la base de datos actual – db.auth(<username>, <password>) – para logearte en un BBDD que exige autenticación • Formateo de resultados: – Para formatear un resultado se puede añadir el comando .pretty()a la operación: db.<collection>.find().pretty() – print() para imprimir sin formateo – print(tojson(<obj>)) para imprimir con formateo JSON y es equivalente a printjson() – printjson() para imprimir con formateo JSON, equivalente a print(tojson(<obj>)) • Más documentación en: • Getting Started with the mongo Shell – http://docs.mongodb.org/v2.2/tutorial/getting-started-with-the-mongo-shell/
  43. 43. 43 Documentos de consulta • Documentos que indican el patrón de claves y valores que deben ser localizados • Ejemplos: – SELECT * FROM things WHERE name="mongo" • db.things.find({name:"mongo"}).forEach(printjson); – SELECT * FROM things WHERE x=4 • db.things.find({x:4}).forEach(printjson); – SELECT j FROM things WHERE x=4 • db.things.find({x:4}, {j:true}).forEach(printjson); – Recuperar el primer elemento que cumple alguna restricción: • printjson(db.things.findOne({name:"mongo"})); – Limitar el número de resultados: • db.things.find().limit(3);
  44. 44. 44 Selectores de Consulta • Los selectores de consulta en MongoDB son como la cláusula where de una sentencia SQL – Se usan para encontrar, contar, actualizar y borrar documentos de una colección • Un selector es un objeto JSON, el más sencillo es {}que sirve para seleccionar todos los documentos (null también funciona). • Ejemplos: – Para encontrar un unicornio femenino usaríamos {gender:'f'} – {field: value} es utilizado para encontrar cualquier documento donde el campo de nombre field es igual al valor value • {field1: value1, field2: value2} corresponde a una sentencia de selección con el operador booleano and – Los operadores $lt, $lte, $gt, $gte y $ne son usados para operaciones menor que, menor o igual que, mayor que, mayor o igual que u operaciones no igual • db.unicorns.find({gender: 'm', weight: {$gt: 700}}) – O lo mismo de un modo más enrevesado • db.unicorns.find({gender: {$ne: 'f'}, weight: {$gte: 701}})
  45. 45. 45 Selectores de Consulta • El operador $exists se utiliza para comprobar la presencia o ausencia de un campo: – db.unicorns.find({vampires: {$exists: false}}) • Si queremos utilizar el operador booleano OR tenemos que hacer uso del operador $or y asociarle un array de tuplas clave/valor sobre los que realizar el OR: – db.unicorns.find({gender: 'f', $or: [{loves: 'apple'}, {loves: 'orange'}, {weight: {$lt: 500}}]}) • Dado que los arrays en MongoDB son objetos de primera categoría se puede comprobar la inclusión de un elemento dentro de un array al igual que si compararamos con un único valor: – {loves: 'watermelon'} devolverá un documento donde watermelon es un valor del campo loves • Un valor de tipo ObjectId asociado al campo _id puede seleccionarse como: – db.unicorns.find({_id: ObjectId("TheObjectId")})
  46. 46. 46 Actualizando documentos • El comando update tiene dos argumentos: el selector where a usar y qué campo a actualizar: db.unicorns.update({name: 'Roooooodles'}, {weight: 590}) • Cuidado!!! Realmente con esa sentencia el documento encontrado que tiene el nombre dado es remplazado con un nuevo documento que mantiene el campo _id pero tiene ahora sólo el campo adicional weight • SOLUCIÓN  cuando quieres sólo cambiar el valor de un campo o varios campos, hay que usar el modificador $set: db.unicorns.update({weight: 590}, {$set: {name: 'Roooooodles', dob: new Date(1979, 7, 18, 18, 44), loves: ['apple'], gender: 'm', vampires: 99}})
  47. 47. 47 Modificadores de update • Aparte de $set se pueden utilizar otros modificadores – El modificador $inc se usa para incrementar el campo por una cantidad positiva o negativa, el tercer argumento lo crea si no existía • db.unicorns.update({name: 'Pilot'}, {$inc: {vampires: -2}}) – Si al unicornio Aurora le gustarán de repente los dulces, podríamos añadir un nuevo valor al campo loves a través del modificador $push: • db.unicorns.update({name: 'Aurora'}, {$push: {loves: 'sugar'}}) • Si queremos que se cree un nuevo documento cuando intentamos actualizar uno no existente (upsert) colocamos un tercer parámetro a true – db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true); • Si queremos que update actualice todos los documentos que cumplen una expresión, un 4º parámetro tiene que ponerse a true – db.unicorns.update({}, {$set: {vaccinated: true }}, false, true);
  48. 48. 48 Búsquedas Avanzadas • Carga perezosa. Por defecto find devuelve un cursor cuya recuperación de datos se pospone hasta que estos son accedidos realmente, en el shell se pre-recuperan y muestran los primeros 20 documentos • Proyecciones. El comando find()toma un segundo parámetro que permite seleccionar los campos a mostrar: – Por defecto el campo _id siempre es mostrado a no ser que se le asigne un 0. – El siguiente comando sólo muestra el campo name de cada unicornio • db.unicorns.find(null, {name: 1, _id: 0}); • Ordenación. El método sort() funciona como el selector de las proyecciones, hay que indicar los campos por los que ordenar, indicando el 1 orden ascendente y el -1 descendente – MongoDB limita el tamaño del sort()cuando se aplica a un campo no indexado. • db.unicorns.find().sort({name: 1, vampires: -1}) • Paginación. Se soporta con los métodos de cursor skip y limit – db.unicorns.find().sort({weight: -1}).limit(2).skip(1) • Conteo. También se pueden contabilizar resultados: – db.unicorns.count({vampires: {$gt: 50}})
  49. 49. 49 MongoDB vs. SQL
  50. 50. 50 Scripting en MongoDB con JavaScript • Cuando escribas scripts en JS para el shell de mongo hay que tener en cuenta que: – Para asignar un valor a la variable db (u otro nombre de variable) hay que utilizar el método getDB()o el método connect() conn = new Mongo(); db = conn.getDB("myDatabase"); db = connect("localhost:27020/myDatabase"); – Dentro del script en JavaScript invoca a db.getLastError() explícitamente para esperar a la conclusión de la operación write – No se pueden utilizar los comandos de ayuda del shell, ej. use<dbname>, show dbs, etc.) dentro de un fichero JavaScript, dado que no son sentencias válidas de JavaScript Shell Helpers JavaScript Equivalents show dbs, show databases db.adminCommand('listDatabases') use <db> db = db.getSiblingDB('<db>') show collections db.getCollectionNames() show users db.system.users.find() show log <logname> db.adminCommand( { 'getLog' : '<logname>' } ) show logs db.adminCommand( { 'getLog' : '*' } ) it cursor = db.collection.find() while( cursor.hasNext() ){ cursor.next(); } // Para imprimir printjson( cursor.next() );
  51. 51. 51 Scripting en MongoDB con JavaScript • Para evaluar código JavaScript desde línea de comando: – mongo test --eval "printjson(db.getCollectionNames())" • Para ejecutar un fichero con código JavaScript: – mongo localhost:27017/test myjsfile.js • Para ejecutar un fichero JavaScript desde el shell: – load("myjstest.js") • Ejemplo: – mongo examplesjsShellIntroUnicornsDB.js • Documentación: – Write Scripts for the mongo Shell • http://docs.mongodb.org/manual/tutorial/write-scripts-for-the-mongo-shell/
  52. 52. 52 Herramientas gráficas para gestionar MongoDB • UMongo en un aplicación de sobremesa para navegar y administrar un clúster MongoDB – Disponible para Linux, Windows and Mac OSX: • http://edgytech.com/umongo/ • MongoDB tiene una interfaz administrativa accesible yendo a: http://localhost:28017/ – Se puede añadir al fichero de configuración la línea rest=true o arrancar el servidor con: mongod --rest • Existen varias alternativas en: – http://docs.mongodb.org/ecosystem/tools/administration-interfaces/ • Fang of Mongo is a web-based user interface built with Django and jQuery. • Futon4Mongo is a clone of the CouchDB Futon web interface for MongoDB.
  53. 53. 53 GridFS • GridFS es una especificación para guardar ficheros grandes en MongoDB – Aunque MongoDB permite guardar datos binarios en objetos BSON, su límite en tamaño es de 16 MB • Ofrece un mecanismo para dividir transparentemente un fichero grande en varios documentos – Cada fichero tiene un objeto de metadatos en la colección files y uno o más objetos chunk en la colección chunks • URL: http://www.mongodb.org/display/DOCS/GridFS
  54. 54. 54 Esquemas de Datos orientados a Documentos • MongoDB no tiene un esquema fijo del modo que nos encontramos en las RDBMS – Sin embargo, tiene lo que se denomina como esquema orientado a documentos o esquema orientado a aplicación. • Consideraciones de Diseño de Modelos de Datos: – ¿Tiene sentido o es posible colocar todos los datos en una colección? – ¿Hay algún peligro de alcanzar los 16MB que existen en todo documento en MongoDB? – ¿Cuáles son los datos que pertenecen a un documento? – ¿Se pueden cambiar los datos en un sitio central (usando referencias) en vez de cambiarse en el conjunto de documentos que contienen esos datos? – Al final la pregunta es “¿Empotramos o no empotramos un documento?” • Dado que MongoDB guarda los datos internamente en formato Binary JSON (BSON), soporta los tipos de datos de BSON
  55. 55. 55 • Cuando se crea una aplicación que usa un RDBMS se pasa un tiempo considerable diseñando las tablas y relaciones entre ellas (database relational schema) • En MongoDB hablamos de diseño de datos dirigido por la aplicación, dado que el concepto de modelado de información en forma de documentos es equivalente al modelado basado en objetos de OOP • Como resultado, a menudo haremos pre-joins colocando datos dentro de un documento que de otro modo estaría repartido en varias tablas en una RDBMS o nuestro código ejecutará programáticamente los JOINs – Leer datos de tres documentos implica que MongoDB tendría que acceder a tres ficheros – Leer los datos empotrados en un único documento sería mucho más rápido • Hay que tener en cuenta que el tamaño máximo para un documento es de 16MB • Por otro lado, no existen restricciones en MongoDB – O juntamos los datos que están asociados en un documento o validamos las restricciones programáticamente Modelado de Datos en MongoDB
  56. 56. 56 Modelado de Datos en MongoDB • La principal diferencia de una base de datos NoSQL orientada a documentos como MongoDB es su carencia de JOINs – La razón para su supresión es que los JOINs no suelen ser escalables – La solución es hacer los JOINs a nivel de aplicación • Si normalizamos nuestros datos hay que hacer una segunda consulta por cada elemento que quiere agregarse • Ejemplo: – Construimos un nuevo documento (objeto) usando explícitamente el identificador: • db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d730"), name: 'Leto'}) – Construimos dos objetos más haciendo que Leto sea su manager: • db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d731"), name: 'Duncan', manager: ObjectId("4d85c7039ab0fd70a117d730")}); • db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d732"), name: 'Moneo', manager: ObjectId("4d85c7039ab0fd70a117d730")}); – Para encontrar los empleados cuyo manager es Leto haríamos lo siguiente: • db.employees.find({manager: ObjectId("4d85c7039ab0fd70a117d730")})
  57. 57. 57 • En MongoDB se usan dos técnicas para modelar relaciones many-to-one y many-to-many, sobretodo en los casos que el “many” hace referencia a “few” • Arrays: db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d733"), name: 'Siona', manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")] }); db.employees.find({manager: ObjectId("4d85c7039ab0fd70a117d730")}) – De modo interesante el método find()funciona independientemente de si se aplica a un vector a un escalar • Documentos empotrados: db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d734"), name: 'Ghanima', family: {mother: 'Chani', father: 'Paul', brother: ObjectId("4d85c7039ab0fd70a117d730")} }); db.employees.find({'family.mother': 'Chani'}) – Los documentos pueden ser consultados usando una notación separada por puntos: family.mother • Otra alternativa es des-normalizar, replicar tus datos a través de varias colecciones – Es una práctica que históricamente ya se ha usado en RDBMS por temas de rendimiento – Introduce la complicación de tener que contrastar las restricciones de los datos (constraints) a nivel de aplicación – MongoDB también soporta DBRefs: http://docs.mongodb.org/manual/reference/database- references/ Modelado de Datos en MongoDB
  58. 58. 58 Ejemplos de Relaciones de Datos • Relaciones uno a uno (1-1) – Los siguientes aspectos deberían tenerse en cuenta cuando se modelan relaciones uno a uno: • La frecuencia de acceso a los documentos • Tamaño de los elementos, teniendo en cuenta la limitación de 16 MB • La atomicidad de los datos y su consistencia – Considera el siguiente código: db.captains.insert({_id: 'JamesT.Kirk', name: 'James T. Kirk', age: 38, ship:'ussenterprise'}); db.starships.insert({_id : 'ussenterprise', name: 'USS Enterprise', class: 'Galaxy', captain: 'JamesT.Kirk'} ); – Un modo más eficiente, en este caso, es colocar el documento del capitán dentro del documento nave: db.starships.insert( {_id: 'ussenterprise1', name: 'USS Enterprise', class: 'Galaxy', captain: {name: 'James T. Kirk', age: 38}} );
  59. 59. 59 • Relaciones uno a muchos (1-N) – Si una nave tiene mucho miembros de tripulación o una nave tiene muchos instructores • ¿Tiene sentido empotrar la lista de toda la tripulación o de instructores dentro del documento nave que tiene un límite de tamaño de 16 MB? – Por tanto, en caso de relaciones 1-N suele ser a menudo conveniente enlazar documentos entre colecciones y además hacerlo desde la colección que guarda muchos valores a la colección que guarda sólo uno. – PISTA. Para tomar una decisión hay que responder a la siguiente pregunta: • ¿Estamos hablando de una relación 1-N o de 1-pocos? – En el segundo caso un array dentro del documento podría ser una mejor opción • Ejemplo: db.starships.insert( { _id: 'ussenterprise1', name: 'USS Enterprise', class: 'Galaxy', captain: { name : 'James T. Kirk', age : 38}, instructors: [1, 2, 3]} db.instructors.insert( { _id: 1, name : 'Tuvok', candidates : [99, 100], starship: 'ussenterprise1'} ); Ejemplos de Relaciones de Datos
  60. 60. 60 • Relaciones muchos a muchos (N-M) – Considera la relación en la que un candidato puede tener varios instructores y viceversa • Varios candidatos serán asignados a un instructor y un instructor será asignado a varios candidatos para que los instruya • En esta relación tendremos dos colecciones (candidates e instructors) y un enlace bi- direccional, dado que cada candidato tiene una lista de instructores y por cada instructor hay una lista de candidatos • Si quisiéramos empotrar los candidatos dentro del documento instructor, sería necesario tener un instructor antes de un candidato, no podrían existir uno sin el otro • Ejemplo: db.candidates.insert( { _id : 99, name : 'Harry Kim', instructors : [1, 2]} ); db.instructors.insert( { _id : 1, name : 'Tuvok', candidates : [99, 100], starship: 'ussenterprise1'} ); • Recuerda que es tu programa el que tendrá que garantizar la consistencia. Por ejemplo, asegurando que existe un candidato cuyo _id es 100 Ejemplos de Relaciones de Datos
  61. 61. 61 • CRUD vs IFUR • Trabajamos en un documento implícito llamado db que representa la base de datos. • Si la base de datos no se modifica explícitamente nos conectamos por defecto a la base de datos test. • Una colección (ships) se crea automáticamente cuando insertamos un documento en ella – db.ships.insert({'name':'USS Prometheus','operator':'Starfleet','class':' Prometheus'}) Create => Insert Read => Find Update => Update Delete => Remove Operaciones CRUD en MongoDB
  62. 62. 62 – Los métodos findOne() y find() usan un documento como primer parámetro y un segundo para indicar los campos sobre los que realizar la selección, observa que el campo _id se muestra por defecto en los resultados: • db.ships.findOne({'name':'USS Defiant'}, {'class':true,'_id':false}) • El método find() devuelve todos los documentos que cumplen el lo especificado en el documento de selección. – En el shell es necesario it para recuperar los siguientes 20 resultados • Necesita los operadores de consulta para realizar consultas más precisas: Operator Description Sample-Query $gt greater than db.ships.find({class:{$gt:’P'}}) $gte greater than or equal db.ships.find({class:{$gte:’P'}}) $lt less than db.ships.find({class:{$lt:’P'}}) $lte less than or equal db.ships.find({class:{$lte:’P'}}) $exists does an attribute exists or not db.ships.find({type:{$exists:true}}) $regex Perl-style pattern matching db.ships.find({name : {$regex:’^USSsE’}}) $type search by the type of a certain element in the document db.ships.find({name : {$type:2}}) Operaciones CRUD en MongoDB: find() y findOne()
  63. 63. 63 Ejemplos de Queries • Algunos ejemplos interesantes con operadores: – db.ships.find({class:{$gte:'P'}}, {'name':true, '_id':false}) • Con $gt, $gte, $lt y $lte es posible realizar operaciones de comparación sobre ciertos valores de un documento – db.ship.find({'type' : {$exists:true}}) • El operador $exists es útil para seleccionar aquellos documentos que tienen un atributo concreto – ATENCIÓN: implícitamente se crearía la colección ship!!!
  64. 64. 64 • Cuidado con el uso por defecto de update que por defecto remplaza el documento seleccionado con los campos del documento pasado como segundo argumento, manteniendo sólo el campo _id: db.ships.update({name : 'USS Prometheus'}, {name : 'USS Something'}) db.ships.find({name : 'USS Something'}).pretty() • Generalmente lo que queremos es remplazar algunos elementos y mantener el resto intacto con el operador $set: db.ships.update({name : 'USS Something'}, {$set : {operator : 'Starfleet', class : 'Prometheus'}}) db.ships.find({name : 'USS Something'}).pretty() • Si queremos quitar un conjunto de valores de un documento se puede hacer uso del operador $unset: db.ships.update({name : 'USS Prometheus'}, {$unset : {operator : 1}}) Operaciones CRUD en MongoDB: update()
  65. 65. 65 • Como en todos los comandos de MongoDB se reutiliza la sintaxis de la operación find() para indicar qué documentos se quieren eliminar • Si emitimos un remove() sin parámetros sobre una colección eliminará uno a uno todos los elementos de la colección • La operación drop() eliminará todos los documentos de la colección más rápido ya que no trabaja a nivel de documento y además elimina los índices – Para colecciones grandes es mejor usar drop() y luego recrear los índices sobre una nueva colección vacía • Ejemplos: db.ships.drop(); db.ships.remove({name : 'USS Prometheus'}) Operaciones CRUD en MongoDB: remove() y drop()
  66. 66. 66 Índices • Los índices mejoran el rendimiento de las consultas y operaciones de ordenación en MongoDB • Operan de modo similar a los de las RDBMS – MongoDB los guarda como un B-Tree que permite la recuperación de listas de claves ordenadas • Se crean con la sentencia ensureIndex(), identificando el sentido de ordenación por campo ascendente (1) o descendente (-1): db.unicorns.ensureIndex({name: 1}); • Para conocer los índices de la colección, escribir: db.unicorns.getIndexes() • Y se eliminan con dropIndex(): db.unicorns.dropIndex({name: 1}); • Para asegurarnos que el índice es único, usamos el atributo unique: db.unicorns.ensureIndex({name: 1}, {unique: true}); • Los índices también pueden ser compuestos: db.unicorns.ensureIndex({name: 1, vampires: -1});
  67. 67. 67 Índices • Para saber si se está usando un índice o no, usamos explain(): db.unicorns.find().explain() • Si la salida indica que se usa un cursor de tipo BasicCursor indica el campo no es indexado, se escanearán más documentos y tardarán más las búsquedas u ordenaciones: { "cursor" : "BasicCursor", // el campo no es indexado "isMultiKey" : false, "n" : 1, "nscannedObjects" : 12, "nscanned" : 12, "nscannedObjectsAllPlans" : 12, "nscannedAllPlans" : 12, "scanAndOrder" : false, "indexOnly" : false, // si la consulta se puede resolver mirando sólo el índice "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, // indica cuánto tardó la consulta "indexBounds" : { }, "server" : "dipinaXPS14z:27017" }
  68. 68. 68 Índices • Si creamos un índice ese campo tendrá asociado un índice de tipo BtreeCursor, optimizándose las operaciones sobre esos documentos { "cursor" : "BtreeCursor name_1", // los campos de consulta son indexados "isMultiKey" : false, "n" : 1, "nscannedObjects" : 1, "nscanned" : 1, "nscannedObjectsAllPlans" : 1, "nscannedAllPlans" : 1, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { "name" : [ [ "Pilot", "Pilot" ] ] }, "server" : "dipinaXPS14z:27017" }
  69. 69. 69 Índices • La colección db.system.indexes contiene detalles de todos los índices de una BBDD de MongoDB: db.system.indexes.find() • Es posible crear índices sobre atributos que se guardan como arrays de valores, así todos los valores del array son indizados – Sin embargo, sólo se permite un “Multikey Index” en un índice • Resumen de operaciones de indexación: Index Command Creating an index db.universe.ensureIndex({galaxy : 1}) Dropping an index db.universe.dropIndex({galaxy : 1}) Creating a compound index db.universe.ensureIndex({galaxy : 1, quadrant : 1, planet : 0}) Dropping a compound index db.universe.dropIndex({galaxy : 1, quadrant : 1, planet : 0}) Creating a unique compound index en la sombra db.universe.ensureIndex({galaxy : 1, quadrant : 1, planet : 0},{unique : true, background:true})
  70. 70. 70 • Para hablar con el servidor de MongoDB, (mongod) debemos hacer uso de un driver, que envía comandos desde la aplicación al servidor, usando un enfoque “fire and forget” • Las escrituras en MongoDB son asíncronas, se gana en rendimiento con el riesgo de perder datos si hay un server crash – No se devuelve un error cuando se produce un insert() o update()que viola una restricción del modelo – Es necesario invocar explícitamente a db.getLastError()después de un insert() – Muchas drivers abstraen esto y proveen un modo de hacer una escritura segura a través de un parámetro extra en el insert {safe => true} – El shell de mongo lo envía cada vez que se realiza un insert() o update() – Cuando se programa una aplicación en mongo debemos decidir si instruir al driver para que lo haga automáticamente o el programador hacerlo manualmente en ciertas ocasiones Escritura Asíncrona
  71. 71. 71 Colecciones Restringidas y Durabilidad • Además de escritura rápida asíncrona MongoDB también soporta colecciones de tamaño limitado (capped collection) – Se crean usando el comando db.createCollection() • db.createCollection('logs', {capped: true, size: 1048576}) – En este caso cuando la colección alcance el 1MB los documentos antiguos son eliminados para hacer espacio • Se puede establecer un límite en el número de documentos con max. • Se respecta el orden de inserción temporal, los resultados son devueltos ordenados cronológicamente • La propiedad de la Durabilidad se preserva en MongoDB, en caso de server crash, si se activa el journal donde se registran todos los cambios por instancia
  72. 72. 72 • La siguiente tabla muestra las opciones de configuración para controlar el modo de escritura y la durabilidad de las operaciones insert() y update() – MongoDB utiliza el nivel acknowledged por defecto. – w – indica al driver que espere al reconocimiento de la escritura y que los índices no se violen. Los datos todavía pueden perderse dado que los datos puede que no estén en disco – j – indica al driver que espere hasta que el cambio ha sido introducido en el journal. W – write mode J – journal mode Meaning (Write Concern) 0 0 Unacknowledged. This is “fire and forget”. 1 0 Acknowledged. Wait for an acknowledgement that the write was received and no indexes have been violated. Data can still be lost. This was formally known as “safe-mode” and should be the default nowadays in the drivers 1 1 Journaled. The most save configuration by waiting for the write to the journal to be completed 0 1 Basically the same as above. Escrituras y Durabilidad
  73. 73. 73 Escrituras y Durabilidad: Write Concerns Acknowledged Journaled
  74. 74. 74 Transacciones • MongoDB no soporta transacciones distribuidas y a través de collecciones – Soporta transacciones atómicas en documentos lo que significa que uno siempre verá o todos los cambios sobre un documento o ninguno – Si ocurre que los datos se ajustan bien dentro de un documento (tamaño menos a 16 MB), dado que las operaciones a nivel de documento son atómicos, no sería necesario más soporte de transacciones. • Algunas alternativas: – Estructura la aplicación de modo que quepa en un sólo documento haciendo uso de atomicidad a nivel de documento de MongoDB: $inc, $set o algunas más complejas como findAndModify • http://docs.mongodb.org/manual/reference/command/findAndModify/ – Tolerar un poco de inconsistencia – Hacer uso de un two-phase commit programáticamente para transacciones con varios documentos: • Es análogo a crear referencias manuales entre colecciones en joins – http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/
  75. 75. 75 Agregación • Las operaciones de agregación procesan registros de datos y devuelven resultados – Es una técnica para simplificar código de aplicación y limitar el uso de recursos, ya que usa operaciones nativas en C++ • MongoDB 2.2 introdujo una framework de agregación modelado en torno al concepto de pipelines de procesamiento de datos – A través de varios pasos los documentos son transformados en resultados agregados • Filtros, transformaciones, agrupamientos, ordenación y cómputos son algunas de las operaciones • Además MongoDB también permite el uso de operaciones MapReduce para hacer agregación • Finalmente, MongoDB ofrece un conjunto de operadores sencillos de agregación como count(), distinct() o group() – http://docs.mongodb.org/manual/reference/operator/aggregation/interface/ Name Description db.collection.aggregate() Provides access to the aggregation pipeline. db.collection.group() Groups documents in a collection by the specified key and performs simple aggregation. db.collection.mapReduce() Performs map-reduce aggregation for large data sets.
  76. 76. 76 MapReduce en MongoDB • MapReduce es un enfoque para procesar datos que tiene dos beneficios: – Puede ser paralelizado permitiendo que largos volúmenes de datos sean procesados a través de varios cores/CPUs y máquinas – Puedes escribir código real en JavaScript para hacer el procesamiento • Se materializa a través de dos pasos: 1. Mapear los datos transformando los documentos de entrada en pares clave/valor 2. Reducir las entradas conformadas por pares clave y array de valores asociados a esa clave para producir el resultado final
  77. 77. 77 MapReduce en MongoDB
  78. 78. 78 • En este ejemplo vamos a contar el número de hits por día en una portal web – Donde cada hit está representado con un log como: resource date index Jan 20 2010 4:30 index Jan 20 2010 5:30 ... – Generando tras el procesamiento la siguiente salida: resource year month day count index 2010 1 20 2 ... • Para la función map emitiremos pares compuestos por una clave compuesta (resource, year, month, day) y un valor 1, generando dato como: {resource: 'index', year: 2010, month: 0, day: 20} => [{count: 1}, {count: 1}] • La función reduce recoge cada dato intermedio y genera un resultado final: {resource: 'index', year: 2010, month: 0, day: 20} => {count: 3} • Documentación en: – http://docs.mongodb.org/manual/reference/method/db.collection.mapReduce/ Ejemplo de MapReduce
  79. 79. 79 • Creamos la colección de entrada con un conjunto de documentos: db.hits.insert({resource: 'index', date: new Date(2010, 0, 20, 4, 30)}); db.hits.insert({resource: 'index', date: new Date(2010, 0, 20, 5, 30)}); ... • La función map: var map = function() { var key = {resource: this.resource, year: this.date.getFullYear(), month: this.date.getMonth(), day: this.date.getDate()}; emit(key, {count: 1}); }; • La función reduce: var reduce = function(key, values) { var sum = 0; values.forEach(function(value) { sum += value['count']; }); return {count: sum}; }; • Ejecutamos mapReduce(): db.hits.mapReduce(map, reduce, {out: {inline:1}}) Ejemplo de MapReduce
  80. 80. 80 Pipeline de Agregación • MongoDB incorpora un mecanismo para poder agregar datos de documentos en diferentes pasos – Cada paso toma como entrada un conjunto de documentos y produce un conjunto de documentos como resultado – Hay operaciones que en un paso dado mantendrán el mismo número de documentos de entrada pero hay otras que los puedes reducir (filtrar) • La siguiente tabla muestra equivalencias entre cláusulas de agregación, incluyendo operaciones de filtrado, agrupación, proyección, ordenación y cálculo, de SQL a la framework de agregación de MongoDB: SQL MongoDB WHERE $match GROUP BY $group HAVING $match SELECT $project ORDER BY $sort LIMIT $limit SUM $sum COUNT() db.records.count()
  81. 81. 81 Operaciones de la framework de agregación en MongoDB • Operaciones: – $project – cambia el conjunto de documentos modificando claves y valores. Es de tipo 1 a 1 – $match – es una operación de filtrado que reduce el conjunto de documentos generando un nuevo conjunto de los mismos que cumple alguna condición, ej. operator="starfleet" – $group – hace el agrupamiento en base a claves o campos indexados, reduciendo el número de documentos – $sort – ordenar en ascendente o descendente, dado que es computacionalmente costoso debería ser uno de los últimos pasos de la agregación – $skip – permite saltar entre el conjunto de documentos de entrada, por ejemplo avanzar hasta el décimo documento de entrada. Se suele usar junto con $limit – $limit – limita el número de documentos a revisar – $unwind – desagrega los elementos de un array en un conjunto de documentos. Esta operación incrementa el número de documentos para el siguiente paso • Ejemplos y documentación de estos operadores en: • http://docs.mongodb.org/manual/reference/operator/aggregation-pipeline/
  82. 82. 82 Pipeline de Agregación
  83. 83. 83 Agrupación • A menudo agrupamos documentos para agregar valores en subconjuntos de documentos – Existen varios acumuladores que se pueden aplicar sobre los campos agrupados • Ejemplo, dados un conjunto de artículos: db.article.aggregate( { $group : { _id : "$author", docsPerAuthor : { $sum : 1 }, viewsPerAuthor : { $sum : "$pageViews" } }} );
  84. 84. 84 Acumuladores sobre Grupos Expression Description Example $sum Sums up the defined value from all documents in the collection db.ships.aggregate([{$group : {_id : "$operator", num_ships : {$sum : "$crew"}}}]) $avg Calculates the average of all given values from all documents in the collection. db.ships.aggregate([{$group : {_id : "$operator", num_ships : {$avg : "$crew"}}}]) $min Gets the minimum of the corresponding values from all documents in the collection. db.ships.aggregate([{$group : {_id : "$operator", num_ships : {$min : "$crew"}}}]) $max Gets the maximum of the corresponding values from all documents in the collection. db.ships.aggregate([{$group : {_id : "$operator", num_ships : {$max : "$crew"}}}]) $push Pushes the value to an array in the resulting document db.ships.aggregate([{$group : {_id : "$operator", classes : {$push: "$class"}}}]) $addToSet Pushes the value to an array in the resulting document but does not create duplicates. db.ships.aggregate([{$group : {_id : "$operator", classes : {$addToSet : "$class"}}}]) $first Gets the first document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. db.ships.aggregate([{$group : {_id : "$operator", first_class : {$first : "$class"}}}]) $last Gets the last document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. db.ships.aggregate([{$group : {_id : "$operator", last_class : {$last : "$class"}}}])
  85. 85. 85 Perfiles de Logueo • Por defecto MongoDB registra aquellas consultas cuya ejecución es más lenta de 100ms • La configuración de logueo de operaciones puede ser modificada por la siguiente expresión: mongod --profile <level> --slowmx <value>, donde si level es: – 0 indica que se deshabilita el logeo – 1 se loguean sólo las lentas, aquellas que tardan más que el valor del segundo parámetro – 2 se loguean todas las consultas • Desde el shell de MongoDB se pueden consultar y manipular los niveles de logueo con las siguientes expresiones: db.setProfilingLevel(1, 5); db.getProfilingStatus(); • Se pueden visualizar los valores capturados por el profiler de MongoDB con el comando: db.system.profile.find()
  86. 86. 86 Replicación • La replicación funciona similar a cómo funciona la replicación en una base de datos relacional – Replicación Master-Slave. Las escrituras son enviadas a un único servidor, el maestro, que sincroniza su estado a uno o varios esclavos • Todos juntos configuran un ReplicaSet • MongoDB puede ser configurado para soportar lecturas en esclavos o no, lo cual puede redundar en la distribución de la carga a cambio de sufrir en consistencia • Si el maestro se cae, un esclavo es promocionado como máster automáticamente • Aunque la replicación puede mejorar el rendimiento (distribución de lecturas) su propósito principal es mejorar en robustez – La combinación de replicación y sharding son un enfoque común • Cada shard puede consistir de un maestro y un esclavo
  87. 87. 87 Replicación
  88. 88. 88 Replica Set • Todos los writes van a un nodo primario (máster) pero es posible hacer lecturas de los nodos secundarios (slave) • Cuando se lee de un nodo esclavo no hay garantía que el dato leído esté actualizado • Sin embargo si sólo se lee y escribe del nodo primario sí hay garantía de consistencia • En el periodo entre la caída de un nodo primario y un nuevo nodo primario es elegido, la consistencia está comprometida. – Todo nodo tiene un nivel de prioridad usado en el proceso de elección – Si el nivel de prioridad es puesto a 0 , ese nodo no puede ser nodo primario • El modo de escritura en un ReplicaSet está configurado por: – El valor del parámetro w indica el número de nodos que han de reconocer el write. Si tenemos tres nodos, dos puede ser un buen valor para w, o la alternativa w=‘majority’ – El valor del parámetro j. Con el valor 1 los datos se escribirán en el journal del nodo maestro
  89. 89. 89 Replica Set • Existen los siguientes tipos de nodos para configurar un ReplicaSet: Type Allowed to vote Can become primary Description Regular yes yes This is the most typical kind of node. It can act as a primary or secondary node. Arbiter yes no Arbiter nodes are only there for voting purposes. They can be used to ensure that there is a certain amount of nodes in a replica set even though there are not that many physical servers. Delayed yes no Often used as a disaster recovery node. The data stored here is usually a few hours behind the real working data. Hidden no no Often used for analytics in the replica set.
  90. 90. 90 Ejemplo de Creación ReplicaSet • Revisar documentación en: – http://docs.mongodb.org/manual/tutorial/deploy-replica- set-for-testing/ • Un listado de métodos para iniciar la replicación disponible en: – http://docs.mongodb.org/manual/reference/method/js- replication/ • El fichero examplesjsreplicasetREADME.txt contiene instrucciones sobre cómo lanzar el Replica Set
  91. 91. 91 Sharding • MongoDB soporta auto-sharding, una técnica de escalabilidad horizontal que separa datos a través de varios servidores. – Una implementación naif podría poner los datos con nombre que empieza entre A-M en el servidor 1 y el resto en el servidor 2 • Sin embargo, MongoDB es mucho más sofisticado
  92. 92. 92 Sharding • El modus operandi de sharding consiste en dividir una colección en varios nodos y luego acceder a sus contenidos a través de un nodo especial que actúa como router (mongos) • Es una decisión que se toma cuando se despliega la base de datos, bien siendo normal o usando sharding • Para usar sharding es necesario que cada colección declare un shard-key – Clave definida para uno o varios campos de un documento – Debe ayudar a dividir la colección en fragmentos (chunks) – Los chunks son luego distribuidos entre nodos, lo más equitativamente posible • La instancia mongos usa la clave shard-key para determinar el chunk y así el nodo utilizado • Las condiciones que un shard-key ha de cumplir son: – Cada documento tiene un shard-key – El valor del shard-key no puede modificarse – Debe ser parte de un índice y debe ser el primer campo de un índice compuesto – No puede haber un índice único a no ser que esté conformado por el shard-key – Si no se usa el shard-key en una operación de lectura esta petición llegará a todos los shards – La clave de shard debe ofrecer suficiente cardinalidad para poder utilizar todos los shards • Documentación: “Convert a Replica Set to a Replicated Sharded Cluster” – http://docs.mongodb.org/manual/tutorial/convert-replica-set-to-replicated-shard-cluster/
  93. 93. 93 Herramientas administrativas • Se pueden obtener estadísticas con stats(): db.stats() • Sobre una colección específica haríamos: db.unicorns.stats() • Los comandos mongodump y mongorestore nos permiten hacer backups de todas las bases de datos, de una concreta o de una colección: – mongodump – hace un backup de todas tus bases de datos en la carpeta dump – mongodump --db DBNAME – backup de una BBDD específica – mongodump --collection COLLECTIONAME – de una colección concreta – mongorestore – usa los mismos switches • Más detalles en: – http://docs.mongodb.org/manual/tutorial/backup-databases-with-binary- database-dumps/
  94. 94. 94 • Ejemplos: – Guardar la base de datos learn en el directorio backup: mongodump --db learn --out backup – Para restaurar sólo la colección unicorns, haríamos lo siguiente: mongorestore --collection unicorns backup/learn/unicorns.bson Herramientas administrativas
  95. 95. 95 • Con mongotop es posible ver cuánto tiempo se pasa con las diferentes operaciones en las diferentes colecciones – Desde línea de comando ejecuta: mongotop • El comando mongostat genera un snapshot del estado general de MongoDB – El parámetro “idx miss %” indica cómo de bien logra MongoDB ejecutar lecturas a partir de índices en memoria • Para más detalles sobre herramientas de monitorización: – http://docs.mongodb.org/manual/administration/monitoring/ Herramientas administrativas
  96. 96. 96 MongoDB (2.4.9) • Written in: C++ • Main point: Retains some friendly properties of SQL. (Query, index) • License: AGPL (Drivers: Apache) • Protocol: Custom, binary (BSON) • Master/slave replication (auto failover with replica sets) • Sharding built-in • Queries are javascript expressions • Run arbitrary javascript functions at server-side • Better update-in-place than CouchDB • Uses memory mapped files for data storage • Performance over features • Journaling (with --journal) is best turned on • On 32bit systems, limited to ~2.5Gb • An empty database takes up 192Mb • GridFS to store big data + metadata (not actually an FS) • Has geospatial indexing • Data center aware • Best used: If you need dynamic queries. If you prefer to define indexes, not map/reduce functions. If you need good performance on a big DB. If you wanted CouchDB, but your data changes too much, filling up disks. • For example: For most things that you would do with MySQL or PostgreSQL, but having predefined columns really holds you back.
  97. 97. 97 Programando MongoDB • MongoDB tiene soporte variado de lenguajes y librerías cliente: – http://docs.mongodb.org/ecosystem/drivers/
  98. 98. 98 MongoDB y Java • Para soporte en Java mirar: – http://docs.mongodb.org/ecosystem/drivers/java/ – http://docs.mongodb.org/ecosystem/tutorial/getting- started-with-java-driver/ • Algunos buenos ejemplos en: – http://www.mkyong.com/tutorials/java- mongodb-tutorials/ – http://www.mkyong.com/mongodb
  99. 99. 99 MongoDB y Java • Creamos un proyecto en Maven para compilar y ejecutar nuestros ejemplos en Java. – El siguiente comando crea un proyecto en Java sencillo: mvn archetype:generate -DgroupId=com.mkyong.core - DartifactId=mongodb -DarchetypeArtifactId=maven- archetype-quickstart -DinteractiveMode=false • Maven descarga el driver de mongodb automáticamente si su dependencia se declara en pom.xml: <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.10.1</version> </dependency> • Alternativamente se puede descargar de: – https://github.com/mongodb/mongo-java-driver/downloads
  100. 100. 100 Programando en Java 1. Creamos una conexión al servidor MongoDB: MongoClient mongo = new MongoClient( "localhost" , 27017 ); 2. Obtenemos una referencia a una BBDD, que MongoDB crea implícitamente si no existe: DB db = mongo.getDB("testdb"); List<String> dbs = mongo.getDatabaseNames(); for(String db : dbs){ System.out.println(db); } 3. Obtenemos una referencia a una colección: DBCollection table = db.getCollection("user"); Set<String> tables = db.getCollectionNames(); for(String coll : tables){ System.out.println(coll); }
  101. 101. 101 Programando en Java 4. Procedemos ahora a realizar las operaciones CRUD, empezando con creación, es decir un insert(): BasicDBObject document = new BasicDBObject(); document.put("name", "diego"); document.put("age", 39); document.put("createdDate", new Date()); table.insert(document); 5. Actualizamos el documento cuando "name=diego": BasicDBObject query = new BasicDBObject(); query.put("name", "diego"); BasicDBObject newDocument = new BasicDBObject(); newDocument.put("name", "diego-updated"); BasicDBObject updateObj = new BasicDBObject(); updateObj.put("$set", newDocument); table.update(query, updateObj);
  102. 102. 102 Programando en Java 6. Hacemos ahora un búsqueda de docs con "name=diego": BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", "diego"); DBCursor cursor = table.find(searchQuery); while (cursor.hasNext()) { System.out.println(cursor.next()); } 7. Borramos el documento con "name=diego": DBCollection table = db.getCollection("user"); BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", "diego"); table.remove(searchQuery); 8. Ejecutamos el programa completo desde examplesjavamongodb folder con el comando: mvn compile exec:java -Dexec.mainClass="com.mkyong.core.App"
  103. 103. 103 Programando en Java • Para más documentación sobre cómo usar la API Java para acceder a MongoDB revisar: – http://api.mongodb.org/java/current/ • La carpeta examplesjavamongodb contiene en su subdirectorio src varios ejemplos de opciones avanzadas para autenticar, insertar, buscar, actualizar y borrar documentos extraídos de: – http://www.mkyong.com/tutorials/java-mongodb-tutorials/
  104. 104. 104 Autenticación en MongoDB • Para hacer que MongoDB solicite autenticación para realizar cualquier operación de modificación de la BBDD, lanzarlo como: mongod –auth • Una vez logeados primero añadimos un usario a la base de datos especial admin y luego a la BBDD que queremos modificar: use admin db.addUser("admin","your-super-password") db.auth('admin', 'your-super-password'); use testdb db.addUser("mkyong","password") • En el código tenemos ahora que logearnos antes de operar sobre la BBDD: MongoClient mongo = new MongoClient("localhost", 27017); DB db = mongo.getDB("testdb"); boolean auth = db.authenticate("mkyong", "password".toCharArray()); • Para probar un ejemplo de código que autentica ejecutar en examplesjavamongodb: mvn compile exec:java - Dexec.mainClass="com.mkyong.core.JavaMongoDBAuthExample"
  105. 105. 105 PyMongo: Python y MongoDB • Documentación de la API: – http://api.mongodb.org/python/current/api/index.html • Tutorial: – http://api.mongodb.org/python/current/tutorial.html • Download el código fuente de – https://github.com/mongodb/mongo-python-driver • Ejecuta el comando python setup.py install • Lo primero instalamos PyMongo – The bson package is an implementation of the BSON format for Python – El paquete pymongo es un driver nativo en Python para MongoDB – El paquete gridfs implementa gridfs encima de pymongo – Nos aseguramos que el servidor de mongo está arrancado • mongod • Más info en: https://pypi.python.org/pypi/pymongo/ • Para ORMs sobre Python – http://docs.mongoengine.org/en/latest/tutorial.html
  106. 106. 106 1. Hacemos una conexión con la BBDD MongoDB from pymongo import MongoClient client = MongoClient() • Podemos alternativamente hacer que el cliente mongo (MongoClient) se conecte a otro puerto con el comando: client = MongoClient('localhost', 27017) • O alternativamente: client = MongoClient('mongodb://localhost:27017/') 2. Accedemos a la BBDD, usando el estilo de acceso a atributos o a diccionarios: db = client.test_database db = client['test-database'] 3. Para acceder a una colección usamos código similar. collection = db.test_collection collection = db['test-collection'] PyMongo: Python y MongoDB
  107. 107. 107 4. Mientras que los datos en MongoDB se representan en JSON, su equivalencia en pymongo son los diccionarios: – El siguiente diccionario puede usarse para representar un post de un blog: import datetime post = {"author": "Mike", "text": "My first blog post!", "tags": ["mongodb", "python", "pymongo"], "date": datetime.datetime.utcnow()} 5. Para insertar datos en MondoDB usamos el método insert posts = db.posts post_id = posts.insert(post) post_id 6. Podemos recuperar el listado de colecciones con el comando: db.collection_names() 7. Para recuperar un solo documento usamos find_one() posts.find_one() PyMongo: Python y MongoDB
  108. 108. 108 8. El método find_one()también permite seleccionar elementos específicos que cumplen un filtro, ej. documentos cuyo autor es “Mike” posts.find_one({"author": "Mike"}) 9. También podemos encontrar un post por _id que en nuestro ejemplo es de tipo ObjectId. posts.find_one({"_id": post_id}) post_id_as_str = str(post_id) posts.find_one({"_id": post_id_as_str}) # No result 10. También se permiten inserciones en bloque con bulk inserts: new_posts = [{"author": "Mike", "text": "Another post!", "tags": ["bulk", "insert"], "date": datetime.datetime(2009, 11, 12, 11, 14)}, {"author": "Eliot", "title": "MongoDB is fun", "text": "and pretty easy too!", "date": datetime.datetime(2009, 11, 10, 10, 45)}] posts.insert(new_posts) PyMongo: Python y MongoDB
  109. 109. 109 11. Consultando más de un documento puede hacerse del siguiente modo: for post in posts.find(): post for post in posts.find({"author": "Mike"}): post 11. Contando los posts: posts.count() posts.find({"author": "Mike"}).count() 11. Consultas de rangos: d = datetime.datetime(2009, 11, 12, 12) for post in posts.find({"date": {"$lt": d}}).sort("author"): print post 11. Indexación: posts.find({"date": {"$lt": d}}).sort("author").explain()["cursor"] posts.find({"date": {"$lt": d}}).sort("author").explain()["nscanned"] 11. Creamos un índice compuesto para reducir la búsqueda: from pymongo import ASCENDING, DESCENDING posts.create_index([("date", DESCENDING), ("author", ASCENDING)]) posts.find({"date": {"$lt": d}}).sort("author").explain()["cursor"] posts.find({"date": {"$lt": d}}).sort("author").explain()["nscanned"] # Ahora la consulta está usando un BtreeCursor y sólo escanea los dos documentos encontrados PyMongo: Python y MongoDB
  110. 110. 110 PyMongo: Python y MongoDB
  111. 111. 111 • El uso de GridFS desde Python está documentado en: – http://api.mongodb.org/python/current/examples/gridfs.html • Hay que hacer uso del paquete gridfs, del objeto GridFS y sus métodos: import gridfs fs = gridfs.GridFS(db) # crea un nuevo fichero y devuelve el _id del fichero creado b = fs.put(fs.get(a), filename="foo", bar="baz" # get devuelve un fichero out = fs.get(b) out.read() GridFS con PyMongo
  112. 112. 112 Node.js: Server-side JavaScript • La mayoría de nosotros ha usado JavaScript como un mecanismo para añadir interactividad a las páginas web • Con la aparición de jQuery, Prototype y otros nos hemos dado cuenta que es un lenguaje que sirve para algo más que hacer un window.open() – Sin embargo, todas estas innovaciones eran para JavaScript como lenguaje en la parte cliente • Node.js nace para permitir usar JavaScript también en la parte servidora – Sin embargo, tu enfoque de desarrollo tiene que cambiar radicalmente • Va a estar basado en un enfoque asíncrono guiado por eventos • URL: http://nodejs.org/
  113. 113. 113 Full-Stack JavaScript • Todos los navegadores (Opera, Chrome, Firefox, Iexplorer) pelean por incorporar las últimas capacidades de HTML5 • La combinación HTML5+JavaScript se está configurando como “la plataforma de aplicaciones web” para el front-end e incluso back-end – Con JavaScript se puede ya programar tanto la parte cliente que se ejecuta en el navegador como la parte servidora alojada en el servidor Web con frameworks como Node.js o motores de BBDD NoSQL como MongoDB
  114. 114. 114 Mean.io • MEAN is a fullstack javascript platform for modern web applications – MongoDB is the leading NoSQL database, empowering businesses to be more agile and scalable. – Express is a minimal and flexible node.js web application framework, providing a robust set of features for building single and multi-page, and hybrid web applications. – AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop. – Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. • URL: http://www.mean.io/
  115. 115. 115 Mean.io
  116. 116. 116 • Node.js sirve para escribir en JavaScript programas en la parte servidora usando un enfoque orientado a eventos • La instalación del driver oficial Node.js para MongoDB se realiza con el siguiente comando: npm install mongodb • El soporte de node.js en MongoDB aparece detallado en: – http://docs.mongodb.org/ecosystem/drivers/node-js/ • Tutorial: – http://mongodb.github.io/node-mongodb-native/api- articles/nodekoarticle1.html MongoDB y node.js
  117. 117. 117 • Ejemplo sencillo de código en node.js con driver nativo MongoDB: // Retrieve var MongoClient = require('mongodb').MongoClient; // Connect to the db MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) { if(err) { return console.dir(err); } var collection = db.collection('test'); var docs = [{mykey:1}, {mykey:2}, {mykey:3}]; collection.insert(docs, {w:1}, function(err, result) { collection.find().toArray(function(err, items) {}); var stream = collection.find({mykey:{$ne:2}}).stream(); stream.on("data", function(item) {}); stream.on("end", function() {}); collection.findOne({mykey:1}, function(err, item) {}); }); }); • Documentación: – http://mongodb.github.io/node-mongodb-native/api-articles/nodekoarticle1.html – https://github.com/christkv/node-mongodb-native MongoDB y node.js
  118. 118. 118 Desplegando Node.js en Heroku • Documentation in: https://devcenter.heroku.com/articles/nodejs#visit-your- application • Signup in heroku: https://api.heroku.com/signup/devcenter • Install heroku toolbelt: https://toolbelt.heroku.com/ – This ensures that you have access to the Heroku command-line client, Foreman, and the Git revision control system. • Type in: heroku login • Create file web.js: var express = require('express'); var app = express.createServer(express.logger()); app.get('/', function(request, response) { response.send('Hello World!'); }); var port = process.env.PORT || 5000; app.listen(port, function() { console.log("Listening on " + port); });
  119. 119. 119 – Declare dependencies for npm with package.json: { "name": "arab2romanconversor", "version": "0.0.1", "dependencies": { "express": "3.x", "mongodb": "1.4" }, "engines": { "node": "0.10.x", "npm": "1.3.x" } } – Use npm to install your dependencies: npm install – Create a Procfile for the sample app we’ve been working on: • web: node web.js – You can now start your application locally using Foreman (): foreman start – Use git to create a local repository: • git init • git add . • git commit -m "init“ – Deploy your application to Heroku • heroku create • heroku addons:add mongohq • heroku config:get MONGOHQ_URL • git push heroku master – Visit your application • heroku ps:scale web=1 • heroku open Desplegando Node.js en Heroku
  120. 120. 120 Full-Stack JS Mobile Web App • Conversor de números romanos a Árabes – Interfaz HTML5/CSS generada con jQueryMobile Codiqa – Parte servidora realizada con Node.js – Conversión en aplicación móvil con la ayuda de PhoneGap Build https://build.phonegap.com/
  121. 121. 121 MapReduce en Mongo y Cloud Computing • MongoDB y Hadoop son una combinación poderosa y pueden ser utilizados para realizar tareas de análisis y procesado de datos almacenados en MondoDB – MongoDB Connector for Hadoop • http://docs.mongodb.org/ecosystem/tools/hadoop/ • Casos de uso: – Agregación batch, data warehouse y datos ETL • MongoDB as a Service: http://tour.mongohq.com/ • BigData y MongoDB: http://www.mongodb.com/learn/big-data
  122. 122. 122 The Emerging Big Data Stack
  123. 123. 123 Comparación MongoDB y CouchDB
  124. 124. 124 Ejemplos de Consulta • Buenos ejemplos de datos y consultas en MongoDB: – http://www.w3resource.com/mongodb/introducti on-mongodb.php • MongoDB CheatSheet: – https://blog.codecentric.de/files/2012/12/Mongo DB-CheatSheet-v1_0.pdf
  125. 125. 125 Conclusión • MongoDB es una gran opción para remplazar a las bases de datos relacionales tradicionales en nuevas aplicaciones o optimizando partes de los modelos de datos de aplicaciones existentes. – Las BBDD NoSQL son una clara alternativa a los RDBMS • Sobre todo para algunas aplicaciones sociales y web que requieren elevada escalabilidad – No son idóneas para todo, de hecho en la mayoría de los casos las RDBMS deberían seguir siendo la primera opción: • La capacidad de hacer JOIN y las garantías ACID son muy importantes para muchas aplicaciones • Es muy posible que los RDBMS actuales evolucionen para incorporar capacidades de NoSQL
  126. 126. 126 Referencias • MongoDB official site: – http://www.mongodb.org/ • Using the mongo Shell – http://docs.mongodb.org/v2.2/mongo/ • Mongo Shell Quick Reference: – http://docs.mongodb.org/v2.2/reference/mongo- shell/ • MongoDB: First Contact by Thomas Jaspers – https://blog.codecentric.de/en/2012/11/mongodb- first-contact/
  127. 127. 127 Referencias • Aggregation – http://docs.mongodb.org/manual/aggregation/ • Deploy a Replica Set for Testing and Development – http://docs.mongodb.org/manual/tutorial/deploy- replica-set-for-testing/ • Convert a Replica Set to a Replicated Sharded Cluster – http://docs.mongodb.org/manual/tutorial/convert- replica-set-to-replicated-shard-cluster/
  128. 128. 128 Referencias • The Little MongoDB Book by Karl Seguin – http://openmymind.net/2011/3/28/The-Little- MongoDB-Book/ • MongoDB: First Contact, serie dar artículos por Thomas Jaspers: – https://blog.codecentric.de/en/2012/11/mongod b-first-contact/
  129. 129. 129 MongoDB: la BBDD NoSQL más popular del mercado 21 Mayo de 2014, 9:00-14:00 Parque Tecnológico de Zamudio. Edificio Tecnalia, #204, Bizkaia Dr. Diego López-de-Ipiña González-de-Artaza dipina@deusto.es http://paginaspersonales.deusto.es/dipina http://www.slideshare.net/dipina Apuntes + Ejemplos + Docs + Downloads disponibles en: https://www.dropbox.com/sh/yz51jkr9y6t3c51/iXm679-WvJ/MongoDB

×