0% encontró este documento útil (0 votos)
3 vistas

noSQL_Mongo2

El documento proporciona una introducción a MongoDB, destacando sus características como base de datos documental, su uso de BSON para almacenamiento y su flexibilidad en comparación con bases de datos relacionales. Se describen operaciones básicas como la creación, consulta, actualización y eliminación de documentos, así como el uso de JSON y BSON. Además, se presentan comandos y ejemplos prácticos para gestionar datos en MongoDB.

Cargado por

Nieves Sánchez
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
3 vistas

noSQL_Mongo2

El documento proporciona una introducción a MongoDB, destacando sus características como base de datos documental, su uso de BSON para almacenamiento y su flexibilidad en comparación con bases de datos relacionales. Se describen operaciones básicas como la creación, consulta, actualización y eliminación de documentos, así como el uso de JSON y BSON. Además, se presentan comandos y ejemplos prácticos para gestionar datos en MongoDB.

Cargado por

Nieves Sánchez
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 102

icemd

@icemd

linkd.in/ICEMD

CanalICEMD

icemd

MongoDB
Sub-puntos de la sesión
Guillermo Ortiz Ferández, Arquitecto Añadir
BigData en Orange foto

Ingeniero Informático. He trabajado 14 años y


Perfil facebook
desde el 2012 trabajo con exclusivamente con @nickname twt
tecnologías BigData. Perfil linkedin

He trabajado en diferentes empresas de varios


sectores y actualmente trabajo en el (añadir otros si se

departamento de DSI de Orange como Arquitecto desea)

y BigData Engineer.

2
Documento

• ¿Qué es un documento?
• Es un contenedor de datos que puede estar estructurado y se
recupera y almacena en un formato
• Los datos pueden ser textos, fechas, números, imágenes,
etc
• Formatos típicos son JSON, XML, etc
Documento Ejemplos

• { "id": 1, "name": "A green door", "price": 12.50, "tags":


["home", "green"] }
Documento Ejemplos

• { "id": 1, "name": "A green door", "price": 12.50, "tags":


["home", "green"] }
• <?xml version="1.0" encoding="UTF-8"?>
<addresses>
<name>Joe Tester</name>
<street>Baker street 5</street>
<wrongExtraField/>
</wrongClosingTag>
</addresses>
Base de datos relacionales

• Las bases de datos relacionales están pensadas para


trabajar con esquemas fijos y bien definidos
• No están pensadas para cuando queramos guardar datos
con diferentes esquemas
• Si la estructura de los datos cambia, tenemos que cambiar
el esquema de la base de datos en la mayoría de los casos
Propiedades de los documentos

• No están tan ligados al esquema, por lo que tienen una


estructura flexible (schema-less)
• Pueden tener otros documentos embebidos
• Se pueden almacenar referencias a otros documentos
• Es la unidad básica de las bases de datos documentales
Base de datos documental

• Una base documental gestiona y recupera documentos,


nos da las siguientes características
• Atomicidad a nivel de documento
• Generación de índices simples o compuestos
• Escala horizontalmente
• Seguridad
• Concurrencia
• Normalmente tenemos un ID con el que podemos acceder
a los documentos independientemente
Introducción a MongoDB

• MongoDB es la base documental más famosa


• OpenSource https://github.com/mongodb/mongo
• Escrita en C++
• Multiplataforma
• Ofrece replicación y HA (Replica Sets)
• Particionamiento y balanceo de carga (Sharding)
• Escala horizontalmente
• Todas las operaciones se pueden hacer a través de la
consola con JSON
Introducción a MongoDB (cont.)

• Ha evolucionado rápidamente
• La comunidad está muy activa
• Hay mucha documentación
• Buen rendimiento
• Se puede acceder a MongoDB a través de muchos
lenguajes de programación
• Fácil de administrar gracias a la consola
• Herramientas para ver rendimientos, exportar, importar, etc
• Muchos casos de uso con éxito
Introducción a JSON

• JSON (JavaScript Object Notation) es un formato para


intercambio de datos liviano
• Fácil de entender para máquinas y para seres humanos
• Permite valores simples, anidados y arrays
• La estructura es muy simple
• Se empiezan y terminan los bloques con llaves
• Los arrays están entre corchetes
• Los valores tienen formato clave : valor
Introducción a JSON

• Hay varios tipos de datos


• String
• number
• object
• char
• array
• null
• boolean
Introducción a JSON
Introducción a BSON

• BSON son JSON serializados en array de bytes


• El tamaño y la velocidad de búsqueda es más rápida que
en JSON
• Es el formato que usa MongoDB internamente
• MongoDB puede buscar nativamente dentro de este
formato
• No se puede exceder el tamaño en 16MB por documento
con BSON
• MongoDB puede construir índices sobre elementos internos
Introducción a BSON (cont.)

• Como mucho se pueden tener 100 niveles de anidamiento


• Si el documento tiene un tamaño mayor de 16MB se puede
usar GridFS
• Se guardan internamente en chunks
• Se puede acceder únicamente a las partes que nos interesan
Introducción a BSON

• Tipos de datos
• Cadena de caracteres (String)
• Enteros de 32 o 64 bits
• Tipo de dato real de 64 bits
• Date (número entero de milisegundos en Tiempo Unix)
• Array de bytes(datos binarios)
• Booleans
• Nulo
• Objeto BSON
• Array BSON
• Expresiones regulares
• Código JavaScript
Introducción a BSON

• Ejemplo de cómo se guardar BSON


Introducción a BSON

• Cuando consultamos a MongoDB nosotros veremos los


datos no serializados
• Todo documento en BSON tiene dos partes
• Clave , este campo es el _id
• Cuerpo
• El campo _id puede ser generado por el cliente
• Si no se define Mongo generará un _id único por nosotros
• El tipo del campo _id es ObjectId
• ObjectId se guarda en 12bytes
Relación MongoDB - RDBMS

• Cada elemento de una RDBMS tiene su correspondiente en


MongoDB

RDBMS MongoDB
Base de datos Base de datos
Tablas Colecciones
Filas Documentos
Columnas Campos
Índices Índices
Clave primaria _id
Servicios MongoDB

• MongoDB nos da varias herramientas una vez instalado


• mongod, servidor mongo, debemos de arrancar este proceso cuando
queramos arrancar MongoDB
• mongos, balanceador para sharding
• mongo, cliente mongo
• mongoexport, exporta una colección en JSON o CSV
• mongoimport, importa ficheros JSON o CSV
• mongodump, genera un dump de la base de datos
• mongorestore, carga un dump en la base de datos
• mongostat, medir estadísticas de rendimiento
• mongofile, permite escribir y leer ficheros en formato GridFS
• bsondump, muestra BSON’s en formato legible
Importar fichero MongoDB

• Como vemos es posible importar JSON o CSV con la


operación mongoimport
• -d parámetro para definir la base de datos
• -c parámetro para definir la colección
• --type CSV/JSON define el formato del fichero
• --file indica el fichero a importar
• --headerline, indica que use la primera línea del fichero para los
nombres de las cabeceras
• Ejercicio importar fichero CSV
Introducción a la Consola

• La consola de MongoDB la usaremos para la mayoría de


tareas administrativas y consultas rápidas
• Soporta JavaScript
• Para ver la ayuda podemos usar el comando help
Comandos MongoDB

• Hay otros comandos que nos pueden dar información sobre


nuestra base de datos
• Con stats nos da información sobre una colección o una base
de datos
• En la función stats se pueden indicar en formato JSON
opciones para sacar más información de la que nos da por
defecto
Comandos en MongoDB

• db nos da el la base de datos donde nos encontramos


• use bd nos permite cambiar de base de datos
• show databases nos muestra todas las base de datos que
tenemos en nuestro sistema
Creación de documentos

• Para insertar se usan los comandos


• insertOne
• insertMany
• insert

• Como es “schema-less” podemos insertar el JSON que


queramos, no tenemos que respetar los documentos que
existen
• Cuando usamos insertMany no hay atomicidad en la
operación, para separar los documentos se deben de
insertar como un array entre “[ {json1}, {json2}, ..]”
Creación de documentos

• insertOne
• Es una operación atómica

• Ejercicio Insertar Documentos


Consulta de documentos

• Para buscar documentos se usa el comando find


• Es posible realizar filtros en el comando find de la misma
manera que existen claúsulas WHERE en SQL
• No es posible hacer JOIN’s
Consultas Avanzadas

• Para buscar se usa el comando find


• Podemos buscar todos los documentos
• db.myCollection.find()
• O buscar un elemento en concreto usando el formato JSON para
realizar el filtrado
• db.myCollection.find({campo : “valorFiltrar”})
• Se puede usar la claúsula pretty para formatear la salida
• db.myCollection.find().pretty()
• Se pueden usar operadores como in, or, exist,
operadores aritméticos, etc.
Consultas Avanzadas
• Podemos tener documentos con cientos de campos, pero nos pueden
interesar solo unos pocos campos
• Debemos de poner una segunda clausula, con 0 o 1
• 1 indica que sólo queremos ese campo
• 0 indica que queremos todos menos ese campo
- db.students.find({"student_id":20},{"scores.english":1})
Consultas Avanzadas
• Podemos usar comparadores
• $eq
- db.inventory.find( { qty: { $eq: 20 } } )
• $gt
- db.inventory.find( { qty: { $gt: 20 } } )
• $gte
- db.inventory.find( { $nor: [ { price: 1.99 }, { sale: true } ] } )
• $in
- db.inventory.find( { qty: { $in: [ 5, 15 ] } } )
• $lt
• $ne (not equal)
- db.inventory.find( { qty: { $ne: 20 } } )
• $nin
- db.inventory.find( { qty: { $nin: [ 5, 15 ] } } )
Consultas Avanzadas
• Podemos usar operadores lógicos
• $and
- db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )
• $not
- db.inventory.find( { price: { $not: { $gt: 1.99 } } } )
• $nor
- db.inventory.find( { $nor: [ { price: 1.99 }, { sale: true } ] } )
• $or
- db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
• Ejercicio Consultas Simples
Consultas Avanzadas
• Podemos realizar consultas sobre los campos
• $exist
- db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )
- Nos devuelve los documentos con el campo qty que exista y que no sea ni 5 ni
15
• $type
- db.addressBook.find( { "zipCode" : { $type : "number" } } )
Consultas Avanzadas
• Otro tipo de operaciones
• $mod, para calcular el módulo de un campo
- db.inventory.find( { qty: { $mod: [ 4, 0 ] } } )
- Nos devuelve los documentos con el campo qty módulo 4 igual a 0
• $regex
- db.products.find( { sku: { $regex: /789$/ } } )
- Equivalente a WHERE sku like “%789”
Consultas Avanzadas
• Operaciones con arrays
• $all, es equivalente a un $and con todas las operaciones
- { tags: { $all: [ "ssl" , "security" ] } }
- { $and: [ { tags: "ssl" }, { tags: "security" } ] }
• $size, devuelve los array con un tamaño determinado
- db.collection.find( { field: { $size: 2 } } );
Borrado de documentos

• Para borrar documentos se usan las operaciones


• deleteOne
• deleteMany
• Es posible definir un filtro y nivel de borrado
• Ejercicio de borrados
: : : : :
db.people.update( { name "Andy" }, { name "Andy", rating 1, score 1 }, { upsert true } )

Update en MongoDB

• La operación update nos permite actualizar documentos


• Sustituye los documentos que cumplen la condición por los
documentos dados en la instrucción
• db.people.update(
{ name: "Andy" },
{
name: "Andy",
rating: 1,
score: 1
},
{ upsert: true }
)
Update en MongoDB

• La opción upsert sirve para que realice insert si no existe el


documento o update si existe.
• La opción multi sirve para que actualice todos los
documentos de la base de datos, en caso contrario solo
actualiza el primero.
• La opción writeConcern sirve para configurar el modo de
escritura.
• update reemplaza los documentos, si queremos modificar
campos se usa la función set
Operaciones de actualización

• $inc, sirve para incrementar o decrementar un valor


• db.products.update(
{ sku: "abc123" },
{ $inc: { quantity: -2, "metrics.orders": 1 } }
)
• $min, $max, se encarga de comparar un campo y actualizarlo con ese
valor si cumple la condición
• db.scores.update( { _id: 1 }, { $min: { “lowScore”: 150 } } )
• $rename, se encarga de renombrar el nombre de un campo de
documentos
• db.students.updateMany( {}, { $rename: { "nmae": "name" } } )
Operaciones de actualización

• $set y $unset se encargan de cambiar el valor de un campo o borrar un


campo de documentos
• db.products.update(
{ _id: 100 },
{ $set:
{
quantity: 500,
details: { model: "14Q3", make: "xyz" },
tags: [ "coats", "outerwear", "clothing" ]
}
}
)
• Ejercicio de actualizaciones
Operaciones con Arrays

• $pop, elimina un elemento del array


• Con valor -1 borra el primer elemento
• Con valor 1 borra el último elemento
• { _id: 1, scores: [ 8, 9, 10 ] }
- db.students.update( { _id: 1 }, { $pop: { scores: -1 } } )
• $pull, borra todas las instancias de un elemento en un array
• $push, añade un elemento al array
• db.students.update(
{ _id: 1 },
{ $push: { scores: 89 } }
)
• $position, indica donde insertar el elemento dentro de un array
Operaciones con Arrays

• Ejemplo funcionamiento de $pull


• {
_id: 1,
fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ],
vegetables: [ "carrots", "celery", "squash", "carrots" ]
}
{
_id: 2,
fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ],
vegetables: [ "broccoli", "zucchini", "carrots", "onions" ]
}
• db.stores.update(
{ },
{ $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } },
{ multi: true }
)
• {
"_id" : 1,
"fruits" : [ "pears", "grapes", "bananas" ],
"vegetables" : [ "celery", "squash" ]
}
{
"_id" : 2,
"fruits" : [ "plums", "kiwis", "bananas" ],
"vegetables" : [ "broccoli", "zucchini", "onions" ]
}
Agregaciones

• Para usar operaciones de agregación seguimos el siguiente esquema


• db.collection.aggregate( [ { <stage> }, ... ] )

• Con la instrucción $group podemos agrupar documento basándonos en


una expresión, es obligatorio el campo _id y con el defines el el campo
con el que agrupar
• Ejemplo
• { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") }
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") }
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }
• db.sales.aggregate( [ { $group : { _id : "$item" } } ] )
• { "_id" : "xyz" }
{ "_id" : "jkl" }
{ "_id" : "abc" }
Operaciones de Agregación

• Ejemplo $project, se usa para quedarnos solo con unos elementos


determinados
• Cada elemento que queramos se define con “1”
• También es posible cambiar el nombre a campos o crear nuevos
• Es útil cuando no queremos todos los campos a lo largo de un pipeline
• { "_id" : 1, "item" : "abc", "price" : 10, "fee" : 2, date: ISODate("2014-03-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "fee" : 1, date: ISODate("2014-03-01T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "fee" : 0, date: ISODate("2014-03-15T09:00:00Z") }
• db.sales.aggregate(
[
{ $project: { item: 1, total: { $add: [ "$price", "$fee" ] } } }
]
)
• { "_id" : 1, "item" : "abc", "total" : 12 }
{ "_id" : 2, "item" : "jkl", "total" : 21 }
{ "_id" : 3, "item" : "xyz", "total" : 5 }
Operaciones de Agregación

• Ejemplo $avg
• { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:12:00Z") }
• db.sales.aggregate(
[
{
$group:
{
_id: "$item",
avgAmount: { $avg: { $multiply: [ "$price", "$quantity" ] } },
avgQuantity: { $avg: "$quantity" }
}
}
]
)
• { "_id" : "xyz", "avgAmount" : 37.5, "avgQuantity" : 7.5 }
{ "_id" : "jkl", "avgAmount" : 20, "avgQuantity" : 1 }
{ "_id" : "abc", "avgAmount" : 60, "avgQuantity" : 6 }
Operaciones de Agregación

• Ejemplo $match

• Se usa para hacer un filtrado de la misma manera que haríamos un


WHERE en SQL.
• { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:12:00Z") }
• db.articles.aggregate(
• [ { $match : { author : "dave" } } ]
• );
• { "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 }
• { "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 }

• Ejercicio de búsquedas complejas


Diseño en Bases de Datos Relacionales

• ¿Cuáles son los pasos en el diseño de


una base de datos relacional?
» Normalización
Diseño en Bases de Datos Relacionales

• ¿Qué nos ofrece la normalización en las


bases de datos relacionales?
Diseño en Bases de Datos Relacionales

• ¿Qué nos ofrece la normalización en las


bases de datos relacionales?
• Esquema bien definido
• Garantiza actualizaciones únicas
• Podemos usar joins
Diseño en MongoDB

• Lo más importante es saber cómo vamos


a acceder a los datos, esto definirá la
estructura de nuestros documentos
Características MongoDB

• MongoDB no puede hacer JOIN’s


• Documentos puedes referenciar a otros documentos, pero
no hay integridad referencial
• Solo hay atomicidad a nivel de documento
• No hay transacciones
• No hay triggers
• El tamaño de documento es 16MB como máximo lo que
podría definir la estructura de nuestro documento
Normalización vs Desnormalización

• Desnormalizar es más común


• Todos los documentos están embebidos o gran parte del dataset
• Más rápido a la hora de hacer lecturas
• Nos da atomicidad y cierta transaccionalidad

• Normalizar
• Escrituras más rápidas

• Qué aproximación a tomar es difícil y depende de los requisitos del


sistema a implementar
• Los datos que queremos recuperar conjuntamente se suelen almacenar
en el mismo documento, lo que requiere cierta desnormalización
Modelo de datos

• 1:1
• Empleado - Curriculum
• Usuario - Perfil
• Lo normal es que haya un único documento y no se acceda a él por
referencia
• Posibles casos
• Un caso extremo es que el documento embebido sea tan grande
que sea necesario sacarlo por rendimiento
• Frecuencia de acceso
• Patrón de actualización
• Atomicidad
Modelo de datos

• 1:N
• Ciudades - Habitantes
• Empresas - Empleados
• Equipo - Jugadores
• Posibles casos
• Depende de cómo sea de grande la relación se puede embeber o
puede que no tenga sentido
• Patrón de acceso
• Atomicidad
Modelo de datos

• N:M
• Libros - Autores
• Alumnos - Profesores
• Posibles casos
• Cantidad de elementos que están relacionados
• Patrón de actualización
Almacenamiento en MongoDB

• Cuando MongoDB escribe un documento en disco, guarda


un espacio extra por si aumenta el tamaño posteriormente
• Si el documento crece demasiado hay que moverlo
• Hay que tener cuidado con esto ya que puede penalizar
mucho las escrituras
• A veces compensa introducir los documentos con datos
adicionales para reservar todo el posible espacio que
necesitará en el futuro.
Datos antiguos con MongoDB

• Hay varias opciones automáticas para no guardar


eternamente los datos en MongoDB
• TTL
• Capped Collection

• O un poco más manual…


• Una colección por mes y borrar la anterior
Capped Collections

• Tiene un tamaño fijo


• Dan muy alto rendimiento al insertar y recuperar
documento
• Documentos se insertan siempre en orden cronológico
• Funcionan de manera similar a un array circular
• Una vez está llena la colección, un nuevo documento
sobreescribe el documento más antiguo
• No se permite hacer updates si el documento crece de
tamaño
Capped Collections

• Se puede comprobar si un colección es capped


• db.collection.isCapped()
Capped Collections

• Se puede comprobar si un colección es capped


• db.collection.isCapped()
• Para recuperar la colección en orden inverso con buen
rendimiento
• db.cappedCollection.find().sort( { $natural: -1 } )
Capped Collections

• Se puede comprobar si un colección es capped


• db.collection.isCapped()
• Para recuperar la colección en orden inverso con buen
rendimiento
• db.cappedCollection.find().sort( { $natural: -1 } )
• Para crear una colección capped
• db.createCollection( "colletionName", { capped: true, size: 100000 } )
• Ejercicio de Capped Collections
Índices en MongoDB

• Los índices se usan para mejorar el rendimiento en las


búsquedas y ordenaciones
• Un índice puede tener más de un campo y cada campo
puede tener una ordenación
• Mejoran lecturas
• Empeoran escrituras
• Existen varios tipos de índices
• simples, compuestos, geoespaciales y texto
Índices en MongoDB

• Para crear índices


• db.myCollection.createIndex( {“age” : 1} )
• Todos los documentos tienen un índice simple por el
elemento _id
• Se pueden crear índices sobre campos embebidos
• db.myCollection.createIndex( {“student.age” : 1} )
Índices en MongoDB

• Es posible crear índices compuestos por más de un campo


• db.myCollection.createIndex( {“age” : 1, “name” : 1} )
• El orden de la definición es importante
• Se pueden crear índices sobre campos embebidos
• db.myCollection.createIndex( {“student.age” : 1} )
• Se pueden crear índices sobre campos que son arrays
Índices en MongoDB

• Es posible crear índices en arrays


• db.weather.createIndex( {“temp” : 1} )
• MongoDB detecta directamente que el campo es un array
• No tenemos que especificar nada a la hora de crear estos
índices
Índices Hash

• Es posible crear índices “hash”


• Es una clase de índices donde solo se puede usar la
igualdad
• Funcionan muy rápido y ocupan poco espacio
• No funciona para campos que son array y no se pueden
crear índices compuestos
• Para definirlos debemos de indicarlo con la palabra
“hashed” en su creación
• db.people.createIndex( {“dni” : “hashed”} )
Índices de texto

• Es posible crear índices textuales


• Soporta varios idiomas que se usan determinar que stop-
words usar
• Para crearlos necesitamos usar la palabra “text”
• db.reviews.createIndex( { comments: "text" } )
• Esta clase de índices son siempre sparse, es decir si no
existe el campo no se indexa el documento
• Esta clase de índices ocupa mucho espacio
• Puede afectar el rendimiento a la hora de insertar nuevos
documentos
Índices en MongoDB

• Para definir el idioma


• db.quotes.createIndex(
{ content : "text" },
{ default_language: "spanish" }
)
Otras características de Índices

• La creación de índices tiene varias opciones


• unique, no permite la creación de elementos con índices duplicados
- db.members.createIndex( { "user_id": 1 }, { unique: true } )
• background, el índice se genera en background
- db.people.createIndex( { zipcode: 1 }, { background: true } )
• TTL, se pueden borrar documento automáticamente dando un TTL a los
documentos
• sparse, sólo indexa los elementos que contiene el campo por el que
queremos indexar. En caso de no existir el campo no se crea el índice, por
lo que ahorra memoria, pero tampoco se mostrará el resultado en la
consulta
- db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
TTL - Time to live

• Nos permite borrar documentos automáticamente después


de un tiempo determinado
• Suele ser útil por ejemplo para colecciones donde tenemos
logs, información de sesión
• Es una propiedad que se pone al índice cuando se crea
• Se usa la propiedad expireAfterSeconds, pasado ese
tiempo se borrará automáticamente
• db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
• Los borra un proceso que corre en backround que corre
cada minuto
• No están soportados en capped collections
• El campo debe ser de un tipo fecha
Índices en MongoDB (cont.)

• Con la función getIndexes es posible ver los índices de


una colección
• db.collection.getIndexes()
Rendimiento de Índices

• Mejoran lecturas
• Empeoran escrituras
• Cada vez que se inserta un documento hay que actualizar el
índice
• Cada vez que se actualiza un campo indexado hay que
actualizar el índice
• Si un documento se mueve hay que actualizar el índice
• Es importante que los índices entren en memoria para no paginar
• Desde la versión 3.0.0 se usa la función createIndex en lugar de
ensureIndex (deprecated)
Queries con Índices

• db.users.createIndex({"age" : 1, "username" : 1})


• db.users.find({"age" : 21}).sort({"username" : -1})
Queries con Índices

• db.users.createIndex({"age" : 1, "username" : 1})


• db.users.find({"age" : 21}).sort({"username" : -1})
• MongoDB puede ir directamente a los registros con edad
21
• Los nombres también están ordenados, sólo tiene que
recorrer el segundo índice en sentido contrario
• Esta query la puede ejecutar MongoDB muy eficientemente
• El orden del índice no importa ya que MongoDB puede
recorrer el índice eficientemente en ambas direcciones
Queries con Índices

• db.users.createIndex({"age" : 1, "username" : 1})


• db.users.find({"age" : {"$gte" : 21, "$lte" : 30}}).sort({"username" :1})
Queries con Índices

• db.users.createIndex({"age" : 1, "username" : 1})


• db.users.find({"age" : {"$gte" : 21, "$lte" : 30}}).sort({"username" :1})
• MongoDB puede buscar directamente los documentos que
tienen una edad entre 21 y 30
• Los nombres no están ordenados
• Esta query es menos eficiente que la anterior
Diseño de Índices

• Es recomendable ver cómo se planifican las consultas con


explain
• Los campos que se consultan por igualdad deben de ir
primero en el índice
• Después los campos que se usan para ordenaciones
• Por último los campos que se usan en rangos
Diseño de Índices

• Es recomendable ver cómo se planifican las consultas con


explain
• Los campos que se consultan por igualdad deben de ir
primero en el índice
• Después los campos que se usan para ordenaciones
• Por último los campos que se usan en rangos
• Los índices deben de caber en memoria
• La función totalIndexSize() nos ayuda a saber cuanto ocupa
un índice
Diseño de Índices

• Es recomendable ver cómo se planifican las consultas con


explain
• Los campos que se consultan por igualdad deben de ir
primero en el índice
• Después los campos que se usan para ordenaciones
• Por último los campos que se usan en rangos
• Los índices deben de caber en memoria
• La función totalIndexSize() nos ayuda a saber cuanto ocupa
un índice
• Los campos que no tienen mucha diversidad de valores no
son buenos para crear un índice
Diseño de Índices

• Se deben de tener en cuenta


• Tipos de queries que se van a realizar
• Escrituras vs Lecturas
• Cantidad de memoria de tu sistema
• Es conveniente supervisar pasado un tiempo el uso de los
índices ya que muchas veces se puede dejar de usar un
índice y se puede borrar
• Generalmente MongoDB sólo usa un índice por query
• Cuando se usa $or es posible usar varios índices
Diseño de Índices

• Si sólo consultas por un campo, lo mejor es un índice


simple
• Si a veces consultas por un campo y otras por ese campo
más algún otro campo, es conveniente un índice
compuesto ya que es más eficiente que dos simples
• Los índices dan una ordenación, si no vale esa ordenación
se hará en memoria, lo que es menos eficiente
• Los índices se pueden reocorrer en las dos direcciones
• Los índices idealmente deben de entrar en memoria para
ser rápidos
• db.collection.totalIndexSize()
Diseño de Índices

• Si tenemos varias colecciones, hay que ver la memoria de


los índices en cada colección
• No siempre es necesario que entre todo el índice en
memoria
• Si sólo se consultan los documentos insertados
recientemente, con tener en el índice lo reciente valdría.
• Es posible compactar colecciones y reconstruir índices con
el comando “compact”
• Ejercicio de índices
Replicación en MongoDB

• MongoDB por defecto no realiza replicación de los datos


• La replicación mantiene copias idénticas de los datos en
múltiples servidores
• Es sólo un conjunto de demonios mongod trabajando
juntos
• Es recomendado para todos los entornos de producción
• Replica Set es el mecanismo de replicación en MongoDB
• El replica set se compone de un nodo primario y varios
secundarios
• Si usas replicación y un nodo se cae se puede seguir
dando servicio
Replicación en MongoDB

• En algunos casos puede aumentar el rendimiento de


lecturas ya que los clientes pueden realizar consultas a
diferentes nodos
• Todos los mongod mantienen una copia del mismo dataset
• Algunos nodos funcionan como primarios o como
secundarios
• El nodo primario es el que recibe todas las escrituras desde
los clientes
Tipos de Nodos en MongoDB
Tipos de Nodos en MongoDB
Tipos de Nodos en MongoDB
Tipos de Nodos en MongoDB

• Sólo hay un nodo primario como mucho y es el único que


puede recibir escrituras y lecturas
• Puede haber entre 1..N nodos secundarios y sólo pueden
recibir lecturas
• Árbitros sólo participan en votaciones para un nuevo
primario
• Árbitros no contienen datos
• Normalmente se usan para tener un número impar de
nodos con un bajo coste
Tipos de Nodos en MongoDB

• La replicación de un nodo primario a un nodo secundario se


hace de manera asíncrona
• Si hacemos consultas sobre los nodos secundarios,
podrían devolver valores incorrectos, MongoDB da
mecanismos para evitar esto
Replicación en MongoDB

• Se recomienda un número impar de servidores


• Para que pueda haber un nodo primario deben de estar
activos al menos la mitad de los servidores del cluster
Replicación en MongoDB
• Una configuración de tres nodos suele ser la estándar a la hora de usar Replica
Set
• El número máximo de nodos es 12 pero sólo 7 pueden votar
• Se debe de configurar cada servidor con la opción –replSet
• mongod --replSet "rs0" --bind_ip localhost,<hostname(s)|ip address(es)>
• Una vez lanzados los servidores se debe de iniciar el RS
• rs.initiate()
• Se puede saber el estado de replicaSet, la configuración actual o añadir nuevos
nodos al replicaSet
• rs.status()
• rs.conf()
• rs.add(“IP:PUERTO”)
• Ejercicio ReplicaSet
Escalar en MongoDB

• Si la carga es demasiado alta un solo servidor no dará el


suficiente rendimiento
• Si el volumen de datos es demasiado grande puede no
entrar en un solo servidor
• Para solucionar estos escenarios se puede usar sharding
• Hay dos métodos para crecer
• Verticalmente
• Horizontalmente
Vertical vs Horizontal

▪ Verticalmente
• Más memoria
• Más CPU’s
• Más capacidad de almacenamiento
▪ Crecer verticalmente tiene bastantes limitaciones
tecnológicas
▪ Incluso si vamos a soluciones cloud estas limitaciones
están presentes
▪ Horizontalmente
• Dividir el dataset entre diferentes servidores
• Añadir más servidores deberían de añadir la capacidad proporcional
Sharding en MongoDB

• Sharding es la manera de particionar los datos cuando un


servidor no es suficiente
• Las colecciones se dividen por una clave de shard
• La clave de shard se divide en rangos dependiendo de los
shard que tenemos
• Es muy importante elegir una buena clave se shard para
tener balanceados los datos (llamados shards).
• Si se consulta por la clave de shard sólo iremos a los shard
necesarios en otro caso se consulta a todos los shards.
Sharding en MongoDB

• El sharding en MongoDB tiene varios componentes Shard


• Cada shard contiene un subconjunto de los datos del dataset
• mongos
• Funciona como si fuera un router y se encarga de redirigir las
consultas a los correspondientes shards
• config servers
• Guardan la metadatos
Shard Key

• Si la consulta contiene la clave de shard solo se ejecuta en


el shard correspondiente
• Si la consulta no contiene la clave se ejecutará
paralelamente en todos los shard
• La clave de shard debe de tener suficiente diversidad
• La clave no debe de ser monótamente creciente
• Se puede usar una clave de shard compuesta
• Idealmente debería ser un campo que se usa muy
frecuentemente en las consultas
Shard Key

• MongoDB divide el dataset usando la clave de shard


• La shard key es inmutable para cada documento
• Se elige al crear la colección y no puede ser cambiada más tarde
• La elección afecta al rendimiento, escalabilidad
• Si elegimos mal una clave de shard puede ser un cuello de
botella
• Se pueden tener dentro de un cluster colecciones donde
estamos usando shard y otras que no
• Hay dos tipos de sharding
• Hashed sharding
• Ranged sharding
Shard Key
• Hashed sharding
• Mongo calcula el hash antes de leer o escribir
• El cliente no tiene que hacer nada
• Esto distribuye muy bien los datos pero da peor rendimiento a la hora de realizar consultas sobre
rangos
• Incluso documentos que tienen una clave similar no seguramente no estén en el mismo chunk
• La clave debería de tener muy buena cardinalidad o muchos valores diferentes
• Sería un buen candidato una fecha que va creciendo
Shard Key
• Ranged sharding
• Documentos con una clave cercana estarán en el mismo chunk
• Esto permite queries muy eficientes sobre rangos de documentos
Mongo – Integración con Flume

▪ Es posible ingestar datos con Flume en MongoDB


▪ Esto es gracias a un conector hecho por la comunidad
• https://github.com/leonlee/flume-ng-mongodb-sink
▪ Para usarlo debes de clonar el repositorio y compilarlo con
Maven (mvn clean package)
▪ Una vez compilado debes de copiar el source y el driver de
java de Flume dentro de Flume pluging.d/mongo/lib
Mongo – Integración con Flume

▪ db define el nombre de la base de datos


▪ collection define el nombre de la colección
▪ model
• Single se insertar todos los documentos en la misma colección
• Dynamic se insertan en una colección dependiendo del header del
evento
▪ Ejercicio Mongo y Flume
Bibliografia
▪ MongoDB: The Definitive Guide
icemd

@icemd

linkd.in/ICEMD

CanalICEMD

¡Gracias! icemd

Nombre ponente, puesto y empresa


contacto si procede

También podría gustarte