Академический Документы
Профессиональный Документы
Культура Документы
josebyte
Este libro est a la venta en http://leanpub.com/mongodbcastellano
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and
many iterations to get reader feedback, pivot until you have the right book and build traction once
you do.
Agradecimientos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Introduccin a MongoDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Un poco de historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Qu es MongoDB? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Documentos JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
BSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Instalacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Instalacin en Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Instalacin en MAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Instalacin en Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Mongo Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
CRUD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
save . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
find y findOne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
remove . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
findAndModify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Operadores especiales: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Modelado de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
ndices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Consideraciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Ver indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Funcionamiento de los ndices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Crear indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
mongotop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
NDICE GENERAL
mongostat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Agregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
ReplicaSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Sharding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Como elegir una shard-key correctamente . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Configurar shard-key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Aadir un shard al cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Bibliografa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Agradecimientos
Me llamo Joseba Madrigal, soy graduado en informtica adems de una persona curiosa y analtica,
me encanta descubrir nuevas tecnologas y ayudar a las personas de mi entorno, por ello he dedicado
un par de meses a escribir este libro que espero ayude a la gente a profesionalizarse en MongoDB.
El libro est escrito para programadores con inters en utilizar MongoDB a un nivel profesional.
El motivo de escribir este libro es que cuando intente realizar el salto del mundo SQL, en el cual
me encontraba muy cmodo, no encontr ninguna documentacin en Espaol y aunque todo buen
desarrollador debe tener buen nivel de ingls, siempre es ms cmodo leer en la lengua materna.
Haba pasado muchos aos trabajando con Oracle PL-SQL y ms de los que me gustara trabajando
con MYSQL hasta que entre en Tapquo S.L. y conoc ms de cerca el mundo no-sql. Fue entonces
cuando me apunt a los cursos de MongoDB-University y comenc a apreciar las virtudes de este
mundo no-sql tan desconocido para m. En apenas 3 meses haba logrado la certificacin oficial
de MongoDb tanto de sus cursos como en su examen, por lo que me di cuenta de que la curva de
aprendizaje es realmente rpida y buena, por consiguiente quera hacerla an mejor para todos los
hispanohablantes que quieran profesionalizarse en MongoDB.
Escrib este libro en mis ratos libres, es difcil encontrar un rato libre cuando tienes una vida con
un trabajo a jornada completa, impartes clases despus de la jornada de trabajo, estudias, tienes
familia, novia y amigos. Estas lneas no hubieran sido posibles sin el apoyo incondicional de todo mi
entorno, desde aqu me gustara agradecer a todos su comprensin y sus nimos. A toda mi familia,
pero en especial a mi hermano Aitor, por ayudarme a mejorar mi ingls, apoyarme, animarme y
adems hacer la revisin final del libro. A mi novia Katy agredezco su paciencia, aguantarme en los
buenos y los malos momentos y por permitirme ponerme en el ordenador para escribir pese a que
no le guste verme delante del PC. A mis amigos les agradezco que me ayuden a desconectar, lo cual
es imprescindible de vez en cuando. A todos ellos les estar eternamente agradecido por apoyarme
siempre en todas mis decisiones.
Y como no, gracias a ti por descargar este libro, espero que sea de tu agrado.
http://www.josebamadrigal.com
Introduccin a MongoDB
Un poco de historia
Actualmente se escucha hablar de BigData, pero antes de comenzar hablando de grandes cantidades
de datos es mejor empezar por el origen, cul es el motivo de la existencia de bases de datos para
Big Data?
Desde el origen de la informtica ha existido la necesidad de almacenar informacin de forma
permanente. Con el trmino permanente se hace alusin a datos almacenados en un medio fsico
como un disco duro ,(la memoria RAM no es almacenamiento permanente), la cual puede ser leda
posteriormente incluso despues de apagar y encender el equipo. Inicialmente se guardaban los datos
en ficheros de texto, pero pronto surgieron limitaciones, es un mtodo poco eficaz, qu ocurre si
cambiamos la estructura de los datos? y si cambiamos algunos datos? inconsistencias? Por ello
surgieron las bases de datos histricas como las jerrquicas, en red o transaccionales. Estas bases
de datos se siguen estudiando actualmente en las universidades pero ya no son utilizadas debido a
sus limitaciones: Complejidad, duplicidad de registros, Integridad referencial, (No existe garanta de
que un registro hijo est relacionado con un registro padre vlido), Desnormalizacin
Debido a esas limitaciones surgieron las bases de datos que se utilizan actualmente. Existen tres tipos
de bases de datos:
Bases de datos relacionales: Hasta la actualidad son las ms usadas, utilizan SQL. Por ejemplo:
Oracle, MS SQL Server, MySQL o MariaDB son bases de datos relacionales.
Bases de datos orientadas a objetos: Se han diseado para trabajar bien en conjuncin con
lenguajes de programacin orientados a objetos como Java, C#, Visual Basic.NET y C++. (No
estn muy extendidas en la actualidad.)
Bases de datos no-relacionales: No utilizan lenguaje SQL y estn orientadas a la escalabilidad,
por ejemplo MongoDB.
Qu es MongoDB?
MongoDB es una base de datos no-relacional de documentos JSON y de cdigo abierto escrito en
C++, que proporciona alto rendimiento, alta disponibilidad y escalabilidad automtica.
El concepto de escalabilidad est totalmente ligado con Big data debido a que cuando se trabaja
con grandes cantidades de datos, en otros tipos de bases de datos es complejo y costoso de gestionar.
Las bases de datos como MongoDb proporcionan escalabilidad automtica, lo cual hace que esta
base de datos sea idonea para grandes cantidades crecientes de informacin.
Introduccin a MongoDB 3
El desarrollo de MongoDB comenz en el ao 2007 por la empresa 10gen3, publicando una versin
final en el 2009 y actualmente se encuentra en la versin 3.0.
Por lo tanto hemos mencionado que MongoDB es una base de datos escalable, no-relacional y orien-
tada a documentos JSON(BSON), pero qu significa no-relacional? y documentos JSON(BSON)?
No-relacional
No-relacional es un trmino nuevo que se aplica a todas las bases de datos que no son relacionales.
Este tipo de base de datos tambin son conocidas como no-SQL o Big Data. MongoDB tiene las
siguientes caractersticas no-relacionales:
No-SQL.
No tiene JOINs.
No tiene esquema.
Escala horizontalmente.
No tiene transacciones atmicas para multiples documentos.
No-SQL
MongoDB no usa SQL como lenguaje de consultas, en su lugar dispone de una serie de mtodos en
JavaScript que permiten realizar consultas y operaciones.
No tiene JOINs
En MongoDB no se puede hacer una relacin entre dos colecciones, no existen las join del mundo
SQL. La razn es que MongoDB est orientado a ser escalable y las join de las bases de datos
relacionales escalan muy mal.
Sin esquema
Una misma coleccin (en sql: coleccin==tabla) de documentos puede contener documentos con
distinto formato, a esto se le llama schemeless o sin esquema. Es decir podremos tener ,por
ejemplo, una coleccin de usuarios en donde guardemos datos diferentes para cada usuario. A esa
capacidad le llamamos polimorfismo.
Introduccin a MongoDB 4
Escalabilidad horizontal
Uno de los motivos ms importantes por el que se han creado las bases de datos no-relacionales
es por la escalabilidad. Actualmente cada vez ms nos encontramos con gran cantidad de datos
en diferentes servidores. Las bases de datos relacionales son lentas y poco escalables en esos
casos, no estn pensadas para que la informacin almacenada sea muy grande y se encuentre
distribuida, por ello ha surgido MongoDB. Este sistema de base de datos tiene la capacidad de escalar
horizontalmente correcta y fcilmente sin penalizacin. Un sistema escala horizontalmente bien si
al agregar ms nodos al mismo, el rendimiento de ste mejora. Quiz ahora entiendas un poco mejor
el trmino que comentamos anteriormente que se usa para estas bases de datos, estn diseadas para
grandes cantidades de informacin, por ese motivo son conocidas tambin como bases de datos de
Big Data.
Documentos JSON
MongoDB est orientada a documentos en JavaScript Object Notation (JSON), por lo que
almacenamos documentos en lugar de registros o filas.
Un ejemplo de un documento JSON puede ser:
1 {
2 "name" : "Joseba",
3 "surname" : "Madrigal",
4 "age" : 28,
5 "skills" : ["javascript", "MongoDB", "jquery", "angularjs", "php"],
6 "address" : {
7 "street_address": "23 Elm Drive" ,
8 "city": "Palo Alto",
9 "state": "California",
10 "zipcode": "94305"
11 }
12 }
Ms adelante comentaremos los tipos de datos de JSON y veremos que internamente se almacenan
BSONs. Existe un lmite de 16MB por documento en MongoDB. En 16MB cabe mucha informacin
y si tuvisemos que introducir ms podramos partir esa informacin en varias colecciones. Para
usar documentos ms grandes MongoDB proporciona GridFS.
JSON es un estndar y puedes saber ms en JSON.org
BSON
Pese a que nosotros a priori en MongoDB usemos documentos en formato JSON, MongoDB trabaja
internamente con BSON (JSON Binario). Un BSON no es ms que la representacin binaria de un
documento JSON.
Puedes ver ms informacin en BSONspec. BSON extiende del modelo JSON para proporcionar
tipos de datos para una correcta codificacion y decodificacin en los diferentes lenguajes. Por lo
tanto BSON proporciona a MongoDB dos capacidades: 1. Rpida escaneabilidad 2. Tipos de datos
JSON proporciona nicamente 6 tipos de dato:
String
Number
booleans
null
arrays
objetos / documentos
Los tipos de datos que maneja internamente BSON son los siguientes:
http://json.org
http://bsonspec.org
Introduccin a MongoDB 6
Double
String
Object
Array
Binary data
Undefined (Deprecated)
Object id
Boolean
Date
Null
Regular Expression
JavaScript Symbol JavaScript (with scope)
32-bit integer
Timestamp
64-bit integer
Min key
Max key
Esquema BSON
El nombre de campo _id est reservado para la primary key; debe ser nico e inmutable, y
puede ser de cualquier tipo excepto array.
Los nombres no pueden empezar por el signo dlar ($).
Los nombres no pueden contener punto (.).
Los nombres no pueden contener el caracter null.
Instalacin
MongoDB est disponible para: - Windows - Mac - Linux
En la documentacin oficial de MongoDB se indica como instalar MongoDB en cada sistema
operativo, a modo de resumen es de la siguiente forma:
Instalacin en Windows
Debemos descargarnos la versin correcta (64 o 32 bits) de la web oficial de MongoDB.
La extensin del archivo descargado es .msi y haciendo doble click comenzar la instalacin.
Para configurar el entorno es necesario definir el directorio donde guardar MongoDB los datos. Por
defecto es c:\data\db
1 md \data\db
1. Panel de control
2. Sistema
3. Configuracin avanzada
4. Variables de entorno
5. Bajo Variables de sistema busca Path y haz doble click en el.
6. En el valor Variable de esa fila seleccionada debemos aadir al final ; si no existe y aadir
la ruta de instalacion de MongoDb: Por ejemplo yo he aadido al final:
1 ;C:\mongodb\bin
Instalacin en MAC
Existen dos formas de instalar en OSX MongoDB: - Instalar en OSX con Homebrew - Instalar en
OSX manualmente
http://www.mongodb.org/downloads
Instalacin 9
1 brew update
2 brew install mongodb
Instalacin en Linux
Debemos descargarnos los binarios desde web oficial .
Descomprimimos el paquete descargado: tar -zxvf mongodb-linux-x86_64-3.0.2.tgz
Copiamos la carpeta descomprimida a la localizacin desde la que lanzaremos MongoDB: mkdir
-p mongodb cp -R -n mongodb-linux-x86_64-3.0.2/ mongodb
Los archivos binarios de MongoDB se encuentran en el directorio bin/ Para agregar los binarios al
PATH: export PATH=<mongodb-install-directory>/bin:$PATH
Reemplazar <mongodb-install-directory> con la ruta de nuestra carpeta de Mongodb recientemente
descomprimida y copiada.
Antes de iniciar mongod creamos la carpeta donde se encontrarn las bases de datos: mkdir -p
/data/db
http://www.mongodb.org/downloads
http://www.mongodb.org/downloads
Mongo Shell
En la carpeta donde tenemos instalado MongoDB hay una carpeta bin, en ella encontraremos todos
los ejecutables de MongoDB. Los ms usados son:
mongod: es el demonio de base de datos, debemos ejecutarlo y dejarlo en ejecucin para poder
lanzar consultas y trabajar.
mongo: es el shell desde el cual lanzaremos las consultas.
mongos: es un servicio de routing de MongoDB Shard.
Si queremos almacenar un array en una variable: var users = db.usuarios.find() Para ob-
tener el indice 4 o la posicin 4 del cursor almacenado en la variable users creada en la linea
anterior: printjson( users [ 4 ] ) Mongo devolver el usuario en esa posicin: { "_id" :
ObjectId("51a7dc7b2cacf40b79990bea"), "nombre" : "Joseba", "surname" : "Madrigal" }
Cuando accedes a un cursor por un ndice, internamente mongo llama a cursor.toArray() para
convertir el cursor en un array donde poder manejar ndices y almacena TODOS los documentos
que devuelve el cursor en la memoria RAM. Para resultados muy grandes de documentos es posible
que mongo devuelva: out of available memory ya que no cabe todo en la RAM.
CRUD
Las operaciones CRUD (Create, Read, Update, Delete) existen en Mongodb en forma de funciones.
No se puede usar SQL, se utilizan las funciones o mtodos que nos proporciona MongoDB.
Insert
1 db.collection.insert(
2 <document or array of documents>,
3 {
4 writeConcern: <document>,
5 ordered: <boolean>
6 }
7 )
Para insertar un documento en MongoDb utilizaremos la funcin insert sobre la coleccin de una
base de datos. Si la coleccin no existe, la crear automticamente. Por ejemplo:
1 db.people.find();
El _id de este documento ser mjoseba@gmail.com. He elegido una cuenta de correo ya que es
una clave primaria nica e inmutable para la mayora de aplicaciones ,(es muy raro que se cambie
el email), normalmente se suele utilizar como nombre de usuario para el login. Podramos utilizar
el dni perfectamente ya que identifica este tipo de documento, pero debes ser cuidadoso al elegir la
clave, si no crees que puedas hacerlo deja que MongoDb genere automticamente el _id por ti.
update
1 db.collection.update(
2 {<query>},
3 {<update>},
4 {
5 upsert: <boolean>,
6 multi: <boolean>,
7 writeConcern: <document>
8 }
9 )
upsert: true -> Hace que si el documento no existe se cree y si existe lo actualiza. Si lo
establecemos a false ,si existe lo actualiza, en caso contrario no hace nada.
multi: true -> Especificamos que queremos actualizar mltiples documentos, por defecto es
false de modo que solo se actualiza un nico documento, esto es importante ya que en SQL
un update actualiza todas las coincidencias, en MongoDB por defecto multi es false por lo que
solo actualizar la primera coincidencia.
CRUD 14
writeConcer -> Hablaremos de este concepto en el tema de ReplicaSet, se trata de una opcin
para definir en cuantas rplicas de servidores mongo debe estar escrito el cambio para devolver
un OK.
Con el update anterior vamos a editar el documento completo con name Joseba y vamos a
introducir el nombre Jose y active con valor 1.
Realizando esta update perderemos los campos que no hayamos especificado, quedara un documento
tal y como hemos especificado:
Para editar uno o varios campos y preservar el documento o lo que es lo mismo realizar un update
parcial debemos utilizar el operador $set, por ejemplo:
save
.save realiza la misma accin que update con upsert por defecto. Es decir, si no exist el _id insertar
el nuevo documento y si existe lo actualizar.
CRUD 15
1 db.collection.save(
2 <document>,
3 {
4 writeConcern: <document>
5 }
6 )
Por ejemplo:
find y findOne
find({WHERE},{PROJECTION})
Para buscar los documentos que insertemos en la base de datos podemos utilizar find() o findOne().
La diferencia es que find retorna un cursor con todos los documentos coincidentes y findOne solo un
documento, si existiese ms de una coincidencia ser uno al azar. Si lanzamos find() sin argumentos:
1 db.people.find()
Obtendremos todos los documentos de la coleccin. Por el contrario si ejecutamos sin argumentos
findOne() :
1 db.people.findOne()
1 db.people.findOne({"\_id": "mjoseba@gmail.com"})
En este caso retornar nuestro registro y estamos seguros que no hay ms ya que hemos buscado
sobre la clave primaria y nica.
CRUD 16
Si queremos buscar todos los usuarios que se llaman Joseba dentro de la coleccin: db.people.find({name:
Joseba})
Retorna todos los usuarios llamados Joseba.
Si especificamos un segundo parmetro definiremos los campos que queremos recibir: db.people.find({name:
Joseba}, {surname: true, _id:false})
Devuelve los apellidos de las personas que se llaman Joseba: {surname: Madrigal}
remove
1 db.collection.remove(query, {justOne: boolean, writeConcern: document})
Es un borrado de mltiples documentos por defecto a no ser que se especifique justOne a true.
findAndModify
Modifica y retorna un nico documento.
1 findAndModify: <collection-name>,
2 query: <document>,
3 sort: <document>,
4 remove: <boolean>,
5 update: <document>,
6 new: <boolean>,
7 fields: <document>,
8 upsert: <boolean>
Operadores
Podemos utilizar los siguientes operadores para evaluar en nuestras consultas.
Por ejemplo si queremos buscar los usuarios de 18 aos: db.people.find({ age : { $eq : 18 }
} )
Por ejemplo si queremos buscar los usuarios mayores de 18 aos y menores de 50 o de 50 en nuestra
coleccin people:
Si queremos buscar los documentos con una cantidad menor que 20 o un precio de 10: db.inventory.find(
{ $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
Operadores 18
Operadores especiales:
Geoespaciales
$geoWithin: Selecciona geometras dentro de una geometra GeoJSON. Los ndices 2dsphere
y 2d soportan $geoWithin.
$geoIntersects: Seleccionan las geometras con interseccin en un GeoJSON. Los ndices
2dsphere y 2d lo soportan.
$geoIntersects.
$near: Devuelve un objeto geoespacial en la proximidad de un punto. Require un ndice
geoespacial. Los ndices 2dsphere y 2d soportan $near.
$nearSphere: Devuelve un objeto geoespacial en la proximidad de un punto de la esfera.
Require un ndice geoespacial. Los ndices 2dsphere y 2d soportan $nearSphere.
Array
Para los campos que contienen Arrays, MongoDB proporciona los siguientes operadores:
$elemMatch
$slice
$.
$size
Por ejemplo, the inventory collection contains the following document: { "\_id" : 1, "name" :
"Joseba", "languages" : [ "JS", "PHP", "HTML" ] }
Si quisiramos obtener solo los dos primeros elementos del array languages lo haramos de la
siguiente manera: db.inventory.find( { \_id: 1 }, { languages: { $slice: 2 } } )
Modelado de datos
Si vienes del mundo sql estars acostumbrado a crear entidades, aplicar las formas normales En
MongoDb se crean los esquemas de la base de datos orientados al uso que se le da a los datos en la
aplicacin. Este tipo de diseo de esquema se llama Application driven schema. Analizaremos los
datos y los patrones de acceso que se usarn en el programa para crear un esquema a esos datos.
Muchas veces nos encontraremos con la duda de si embeber un documento o no. Por ejemplo en un
blog, imaginemos una coleccin post:
1 {
2 "author" : "Joseba",
3 "title" : "Mongodb introduction",
4 "text" : "MongoDB is a no-sql document oriented data base ...",
5 "comments" : [
6 {"author": "Patxi", "comment": "Thanks for this post!" },
7 {"author": "Juan", "comment": "Nice post!" }
8 ],
9 "tags" : ["javascript", "mongodb", "jquery", "angularjs"],
10 }
1 {
2 nick: "josebyte",
3 pass: "1234",
4 type: "admin",
5 cars:[
6 {marca: "Ford", ao: "2009", matricula:"1234-GGG"},
7 {marca: "Opel", ao: "2001", matricula:"4321-JJJ"}
8 ]
9 }
Relaciones n-m: Si pensamos en el ejemplo anterior y que un coche puede tener varios usuarios
el ejemplo anterior sera n-m y en lugar de embeber los datos en el documento deberiamos
crear otra coleccion:
1 Coleccin usuarios:
2 {
3 nick: "josebyte",
4 pass: "1234",
5 type: "admin",
6 cars:[
7 11154,
8 11155
9 ]
10 }
11
12 Coleccin coches:
13 {"_id": 11154, "marca": "Ford", "ao": "2009", "matricula":"1234-GGG"}
14 {"_id": 11155, "marca": "Opel", "ao": "2001", "matricula":"4321-JJJ"}
Nota: Se podra embeber en usuarios el array de coche o a la inversa, un array conductores dentro
de los documentos coches que contendr el _id de cada usuario de ese coche. Depender de cmo
se va a acceder a los datos en el programa.
Embeber documentos 1-1 y 1-n proporcionar mayor rapidez de lectura. Es importante que se
analicen las lecturas y escrituras que realizar el programa sobre la base de datos para orientar
el modelo de base de datos y mejorar la eficiencia.
ndices
Introduccin
Los ndices en MongoDB funcionan igual que en cualquier base de datos. Si realizamos una consulta
en una base de datos sin usar ndices la consulta ser lenta debido a que se recorrern todos los
documentos de la coleccin para comprobar si se cumple la consulta. Sin embargo si disponemos
de un ndice, los elementos estn ordenados y como sabris no es lo mismo buscar palabras en un
diccionario que en una sopa de letras el diccionario lleva un ndice alfabtico en las palabras.
Consideraciones
Cuando creas ndices debes tener en cuanta lo siguiente:
Ver indices
Puedes ver todos los ndices de la base de datos con la siguiente consulta:
1 db.system.indexes.find()
1 db.setProfilingLevel(2)
1 db.system.profile.find()
Crear indices
Para crear un ndice: db.micoleccion.createIndex({micampo:1}) db.micoleccion.ensureIndex({micampo:1})
//Para versiones previas a 3.0
Podemos crear ndices compuestos de varios campos db.micoleccion.createIndex({{micampo:1
, orden:1})
ndice unico
1 db.micoleccion.createIndex({{micampo:1},{unique:true})
Eliminar duplucados
Si en la creacin indicamos la opcin dropDups:1 eliminaremos los valores duplicados.
Borrar indece:
ndices 23
1 db.micoleccion.dropIndex({micampo:1});
Multikey index
Si creamos un ndice de un campo que es un array ser un ndice multikey. No puedes crear un
ndice compuesto sobre dos campos multikey, en ese caso debes crear dos ndices separados.
Si existe un documento con valores y creas un ndice ya se considera multikey pese a que el resto de
valores sean numricos o string.
Si hacemos un .explain() de una consulta y dice isMultiKey significa que usa es un ndice multikey.
Sparse index
Los ndices creados con la opcin sparse:1 generar ndices solo para los campos con valor disntito de
null. Es usado principalmente en conjunto con unique ya que si no disponen ese campo se considera
que tienen null y hay valores duplicados.
ndices en background
Por defecto se lanzan en foreground y son mas rpidas pero bloquean las escrituras en la misma
base de datos. En background no bloquear las escrituras pero ser bastante ms lento.
Una instancia de mongod solo puede construir un ndice en background por base de datos. Una
creacin de ndices en background permite escrituras pero bloquea el shell.
Indices geoespaciales
Hay dos tipos de indices geoespaciales: * 2D [x,y] * 2D Sphere [long, lat]
2d createIndex({location: "2d", type: 1}) find({ location:{$near:[x,y]} }).limit(30)
1 createIndex({mitexto: "text"})
2 find({$text:{$search:{"dog"}}})
3 find({$text:{$search:{"dog CAT"}}})
mongotop
Muestra tiempos de lectura, escritura y totales por cada coleccin. Podemos lanzarlo con: mongotop
5 Refrescar cada 5milisegundos
mongostat
Muestra update, query delete por query. Nos dice si el ndice est en memoria o no.
Agregation
MongoDB dispone de herramientas para hacer consultas sobre agrupaciones de documentos. Pode-
mos agrupar datos de varios documentos y realizar operaciones sobre esa agrupacin. Utilizaremos
agregaciones por ejemplo para mostrar estadsticas sobre nuestros documentos. Funciona de forma
similar al comando GROUP BY y HAVING de SQL.
Si quisisemos agrupar y contar cuantos usuarios hay por pas:
1 db.usuarios.aggregate([
2 {
3 $group: {
4 "_id": "$pais",
5 "num_usuarios": {$sum: 1}
6 }
7 }
8 ])
Expresiones:
Agregation 26
$sum
$avg
$min
$max
$push
$push
$addToSet
$first -> requiere que ordenes con sort los documentos
$last -> requiere que ordenes con sort los documentos
Si quisiramos sumar los puntos de cada pais que han obtenido los usuarios: db.usuarios.aggregate([
{ $group: { "_id": "$pais", "puntosPorPais": {$sum: "$puntos"} } } ])
Los datos se escriben sobre el primario y luego se replican asincronamente en los secundarios. Los
rbitros nunca pueden convertirse en primarios y unicamente entran en accion cuando el nodo
primario se cae y es necesario votar para elegir un nuevo primario. Para tener un nuevo primario
debes tener una mayora estricta del numero original de nodos.
Cuando un nodo se recupera vuelve como secundario.
Las elecciones de nodo primario se realizan de forma transparente para el usuario.
Veamos como hacer un replicaSet para lograr alta disponibilidad y tolerancia a fallo. Antes de nada
debo decir que lo lgico y natural es que para lograr lo anterior debemos disponer de 3 servidores
distintos ya que si los montamos sobre la misma maquina no estamos solucionando nada en el caso
de que se caiga o se rompa. Aclarado eso y solo con fines educativos crearemos el replicaset sobre
la misma maquina en diferentes puertos (ya sabemos que esta mal pero es solo para aprender).
Lo primero vamos a especificar un nombre para nuestro replicaSet mediante:
Podemos guardarlo y editar esa informacin aadiendo dos miembros ms tal y como pue-
de apreciarse aqu: { "_id" : "rs0", "version" : 1, "members" : [ { "_id" : 1, "host" :
"localhost:27017" }, { "_id" : 2, "host" : "localhost:27018" }, { "_id" : 3, "host" :
"localhost:27019" }, ] }
Imaginemos disponemos de una coleccion pedidos con gran cantidad de informacin almacenada.
Disponemos de varias bases de datos y queremos repartir la informacin de esa coleccion pedidos.
Para ello vamos a crear shards.
S1, S2, S3, S4
Cada shard contine normalmente un replicaSet. Y para gestionarlos y enrutarlos se usa mongos.
Mongos mantendra una especie de pool de conexiones de todos los hosts.
En sharding se realiza una particion de datos por rango para almacenar los datos en funcion de su
shard-key.
Las particiones se realizan basadas en rangos sobre la shard-key.
El shard-key es una clave que define el usuario para dividir los documentos en distintos servidores.
Cuando establecemos un shard-key mongo dividira los valores en chunks. Esos chunks no dejan
de ser una agrupacin de datos en funcion de un campo dado.
Cuando hacemos una consulta, mongod se comunica con mongos y si existe un shard que satisfaga
la consulta, mira los chunks y ve donde tiene que enrutar la consulta. Por ejemplo si definimos el
shard-key con pedido_id y buscamos pedido_id=100. nuestro mongos podria enrutarnos al shard s2
que contiene ese documento despues de mapear los chunks.
Sharding 30
Supongamos que estamos buscando la shard-key para una coleccion de pedidos con order_id, order_-
date y vendor.
Cual es el shard-key ideal para esta coleccion?
Si deseamos seguir los consejos anteriores deberiamos descartar order_id ya que crecera monotona-
mente.
Entre order_date y vendor cual es mejor shard-key? Si vendor tiene suficiente cardinalidad podria
ser una buena eleccin.
El order_date tiene un problema y es que normalmente se ira incrementando y podriamos tener
hotspot asi que no es una gran eleccion. Vendor podria funcionar bien como shard-key.
Configurar shard-key
Esta labor quiza este mas orientada para los DBA pero a continuacin detallo como se realizaria una
configuracion de shards.
Creamos la carpeta donde almacenaremos la base de datos. mkdir /data/configdb
Iniciamos la configuracin: mongod --configsvr --port 27000 --dbpath /data/configdb
Por ejemplo si disponemos de los siguientes hosts:
cfg0.mishard.net cfg1.mishard.net cfg2.mishard.net
Escribiremos lo siguiente para configurarlo: mongos --configdb cfg0.mishard.net:27019,cfg1.mishard.net:27
Nota: Cada mongos shard debe usar la misma configDB string con los mismos nombres de host
en el mismo orden.