MongoDB – Primeros Pasos – 01

logo-mongodb-tagline

Creo que ya conocemos de MongoDB, ya el decir que es una base de datos NoSQL orientada a documentos y que almacena sus datos en formato BSON (JSON Binario) ya suena a cliché. Es una de las base de datos NoSQL más populares, pero, por qué?… Hay muchas razones, una de ellas, está en el hecho de que en contraste con otras bases de datos NoSQL como Redis o Cassandra (Con las que bien puede complementarse) MongoDB da una facilidad extra a los desarrolladores y DBAs que venimos con cierta experiencia en bases de datos relacionales como Oracle o PostgreSQL, ya que varios conceptos básicos como colecciones (tablas), documentos (registros), atributos (columnas o campos), índices (índices), entre otros, son (aunque no iguales) análogos, con la diferencia de que aunque los datos en MongoDB poseen una estructura definida no existe un esquema rígido y fijo como en los RDBMS (Sistemas de bases de datos relacionales). Otra característica que la ayuda a ser la elegida de los desarrolladores es que al proveer sus datos en formato JSON este se adapta fácilmente a cualquier lenguaje de programación.

Pero, ¿Cuándo utilizarla?

A esta pregunta se responde con la forma de trabajar de MongoDB, a diferencia de los RDBMS, MongoDB no posee transacciones y tampoco soporta integridad referencial (no directamente) con joins o relaciones entre distintas colecciones, aunque con cada versión de MongoDB esta brecha de distinciones con los RDBMS está reduciéndose. (Ver Map Reduce y Aggregation Framework)

No veamos esto como una deficiencia, estas distinciones además hacen que MongoDB sea muy rápida y tenga un performance muy superior con respecto a las bases de datos relacionales, por lo que es muy utilizada hoy en día para la aplicación de Big Data e Inteligencia de Negocio. Además también es muy utilizada en aplicaciones tipo CRUD como lo son mucho de los desarrollos web actuales. (Ver MEAN.js)

Además, ¿Quiénes la utilizan?

¿Que quiénes utilizan MongoDB? Aunque las bases de datos NoSQL hoy son algo relativamente (ya no debería serlo para nadie) nuevo… MongoDB es utilizado por empresas importantes en el ámbito de la tecnología como Google o Facebook y en otras empresas que se dedican a promover el imperio norteamericano como New York Times.

Si quieren ahondar más en el cuándo utilizar MongoDB, ventajas y desventajas recomiendo este post.

Ya hemos hablado mucho de MongoDB, vamos a dar nuestros primeros pasos como desarrolladores (aún no como DBAs) en esta base de datos, comenzaremos explicando cómo insertamos los datos en MongoDB:

Antes de insertar datos en MongoDB es bueno saber cómo se instala, eso lo pueden conseguir fácilmente en la documentación oficial de MongoDB. Acá les dejo la instalación en Ubuntu que es de donde estaré llevando a cabo la práctica de estos post de MongoDB.

Una vez instalada y suponiendo que tenemos corriendo el servicio de MongoDB (mongod) en el puerto 27017. Si no lo tuvieramos deberíamos crea un documento para la configuración (es lo más recomendado):

$ nano config.cfg

Y agregarímos lo siguiente al archivo, teniendo en cuenta que los directorios indicados para almacenar los log (logpath) y las bases de datos (dbpath) deben existir:

logpath=/home/user/mongodb/log/mongo.log
dbpath=/home/user/mongodb/data/db

Guardamos el archivo, nos posicionamos en el mismo direcorio donde creamos el archivo, para mayor facilidad y ejecutamos lo siguiente para levantar el servicio:

$ nohup mongod --config config.cfg &

Este proceso casi siempre hay que hacerlo para levantar el servidor de MongoDB en Guindows ya que en la mayoría de las distribuciones Linux el servicio se levanta automáticamente…

Podemos verificar dónde (en qué puerto) está corriendo mongo a nivel local ejecutando lo siguiente:

  $ sudo lsof -iTCP -sTCP:LISTEN | grep mongo

Vamos a la terminal

Antes de comenzar explicaré que la nomenclatura de las terminales donde estaremos ejecutando comandos, son las siguientes:

1.- Si el código comienza con el caracter “dolar” ($) el comando lo ejecutaremos en la terminal del sistema operativo.

2.- Si el comando comienza con el caracter “mayor que” (>) estaremos en el cliente (o shell) de MongoDB.

Para entrar al shell o cliente de MongoDB debemos ejecutar en la terminal:

  $ mongo

Este comando nos conectará a MongoDB en el puerto por defecto (27017) y la base de datos por defecto “test”. También podemos conectarnos a una base de datos de forma directa ejecutando lo siguiente:

  $ mongo localhost:27017/mi-base-de-datos

Por ahora, solo ejecutaremos mongo en la terminal, esto nos llevará al shell de MongoDB. El prompt de MongoDB es un cliente que permite ejecutar código javascript para comunicarse con la base de datos.

Este primer post va a estar orientado a cómo Registrar Datos en MongoDB, para esto es necesario conocer los tipos de datos con los que nos encontraremos y la estructura de un documento JSON.

En MongoDB los documentos JSON se almacenan en Colecciones las cuales poseen una estructura de datos no fija definida por los mismos documentos JSON que se encuentran registrados en estas. Por otra parte, los documentos JSON están compuesto por dos tipos de estructuras de datos:

  1. Una colección de pares nombre : valor , en otros lenguajes esto es conocido como arreglos asociativos, diccionario de datos, tablas hash…
  2. Una lista ordenada de valores, en otros lenguajes esto es conocido como matriz, vector, lista, secuencia.

Un ejemplo de un documento JSON es el siguiente:

 {
     "id" : 1,
     "nombre" : "María",
     "apellido" : "Pérez",
     "edad": 27,
     "fechaDeNacimiento": new ISODate("1987-04-21")
     "hobbies": [
         "Jugar Tenis",
         "Ir de Compras",
         "Ir al Cine",
         "Ir a Fiestas"
     ]
 }
 

En el Shell de Mongo se pueden ejecutar algunas funciones para obtener información de nuestro entorno, alguna de las funciones que nos dan información son las siguientes:

El siguiente comando nos muestra la lista de bases de datos presentes en el servidor con el tamaño que ocupan:

> show dbs;

El objeto “db” es el que más utilizaremos en Mongo, este representa el contexto de la base de datos donde estamos conectados actualmente, al ejecutar esta línea en el Prompt veremos el nombre de la base de datos actual:

> db;

Con el objeto “db” podemos tener información como el de la versión de la base de datos, ejecutando lo siguiente:

> db.version();

Por ejemplo, podríamos ver las colecciones presentes en la base de datos con:

> db.getCollectionNames();

O ver las estadísticas ejecutando:

> db.stats()

El objeto “db” tiene además muchos otros métodos y propiedades que la harán nuestra herramienta principal, además a través de este podremos efectuar operaciones sobre nuestras colecciones. Por otra parte, para cambiar entre bases de datos o crear una base de datos nueva solo hay que ejecutar:

> use miBaseDeDatos;

Si la base de datos “miBaseDeDatos” no existiera se crearía una y el shell se cambiaría a esa nueva base de datos, de existir solo haría esto último.

Si ejecutas el comando “exit” en la shell puedes salir de ella hacia la terminal del sistema:

> exit; // Te vuelves a conectar ejecutando mongo

Para ver más método que pueden ser ejecutados en el shell de MongoDB pueden acceder acá.

Vamos a conectarnos a una base de datos llamadas begin.

> use begin;

Para registrar datos en MongoDB lo podemos hacer desde su shell, mediante un archivo javascript o a través de un archivo json.

1.- Vamos a ver cómo registrar datos desde el shell de MongoDB, para esto hay que entender que las colecciones (a diferencia de las tablas en las bases de datos relacionales) no se crean antes que los documentos que la contienen, no se define una estructura para las colecciones, por tanto las colecciones empiezan a existir cuando se registra un documento en ellas. Para registrar un documento en una colección se hace uso del método “insert” de dicha colección, teniendo este comando el siguiente formato:

> db.<nombreDeLaColección>.insert();

Para comenzar, crearemos una colección llamada estudiante, para esto crearemos primero una variable “nuevoEstudiante” que contendrá un objeto JSON con los datos de un estudiante, y luego utilizaremos el método “insert” para insertar un nuevo documento y a su vez crear una colección nueva (si esta no existiera):

> var nuevoEstudiante = { "nombre" : "Gabriel Alejandro", 
                          "apellido" : "González León",
                          "genero": "M", 
                          "fecha_nacimiento" : new ISODate("1987-10-04"),
                          "curso" : "Desarrollo de Software",
                          "aptitudes" : [
                               "Linux", "Oracle", "PostgreSQL", "MongoDB", 
                               "MySQL", "PHP", "Javascript", "GIT", "Python", 
                               "Ruby", "Java SE", "Java EE", "Node", "jQuery", 
                               "AngularJS", "Yii", "Symfony", "Laravel", 
                               "Django", "ExpressJS", "Rails", "Spring", "Hibernate"
                          ]
                         };
db.estudiante.insert(nuevoEstudiante);

Con las sentencias ejecutadas anteriormente a la base de datos, se pueden apreciar el proceso de inserción de un solo documento a la colección “estudiante”. Al pasar un arreglo de documentos JSON al método insert pudiéramos insertar varios datos a la vez, eso lo lograríamos si ejecutamos lo siguiente:

> var listaDeEstudiantes = [
 {
   "origen" : "V",
   "cedula" : 12,
   "nombre" : "María",
   "apellido" : "Moncada",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1989-11-24"),
   "curso" : "Administración de Base de Datos",
   "aptitudes" : ["Linux", "Oracle", "PostgreSQL", "MongoDB", "MySQL", 
                "Apache", "Glassfish"]
 },
 {
   "origen" : "V",
   "cedula" : 13,
   "nombre" : "José",
   "apellido" : "Pérez",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1992-06-14"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Linux", "Oracle", "PostgreSQL", "MongoDB", "MySQL", 
                "PHP", "Javascript", "GIT", "Python", "Ruby", "Java SE", 
                "Java EE", "Node", "jQuery", "AngularJS", "Yii", "Symfony", 
                "Laravel", "Django", "ExpressJS", "Rails", "Spring", 
                "Hibernate"]
 },
 {
   "origen" : "V",
   "cedula" : 14,
   "nombre" : "Alexander",
   "apellido" : "Sosa",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1991-08-29"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Linux", "Oracle", "MongoDB", "MySQL", "Java SE", 
                "Java EE", "Node", "jQuery", "AngularJS", "ExpressJS", 
                "Spring", "Hibernate"]
 },
 {
   "origen" : "V",
   "cedula" : 15,
   "nombre" : "Carmen",
   "apellido" : "Alvarado",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1987-04-13"),
   "curso" : "Levantamiento de Procesos",
   "aptitudes" : ["Linux", "UML", "BPMN", "Bonita", "Intalio"]
 },
 {
   "origen" : "V",
   "cedula" : 16,
   "nombre" : "Luisa",
   "apellido" : "Ibarra",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1987-04-13"),
   "curso" : "Levantamiento de Procesos",
   "aptitudes" : ["Linux", "UML", "StarUML"]
 },
 {
   "origen" : "V",
   "cedula" : 17,
   "nombre" : "Alex",
   "apellido" : "Kernel",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1987-01-07"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Linux", "PostgreSQL", "MongoDB", "MySQL", "PHP", 
                "Javascript", "GIT", "HTML5", "CSS", "Ruby", 
                "Java SE", "Java EE", "jQuery", "Yii", "Symfony", 
                "Rails", "Spring", "Hibernate"]
 },
 {
   "origen" : "V",
   "cedula" : 18,
   "nombre" : "Sofía",
   "apellido" : "Morales",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1991-03-14"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Linux","PostgreSQL", "MongoDB", "PHP", "Javascript", 
                "HTML5", "Python", "Java EE", "Node", "jQuery", "AngularJS", 
                "Symfony", "Laravel", "Django", "ExpressJS", "Spring"]
 },
 {
   "origen" : "V",
   "cedula" : 19,
   "nombre" : "Edgar",
   "apellido" : "Brito",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1988-08-04"),
   "curso" : "Administración de Base de Datos",
   "aptitudes" : ["Linux", "PostgreSQL", "MySQL", "Apache", "Windows", 
                "Tomcat", "Glassfish"]
 },
 {
   "origen" : "E",
   "cedula" : 21,
   "nombre" : "Pedro",
   "apellido" : "Echenique",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1996-09-24"),
   "curso" : "Administración de Base de Datos",
   "aptitudes" : ["Linux", "Oracle", "MongoDB", "MySQL", "Apache", "Nginx"]
 },
 {
   "origen" : "E",
   "cedula" : 22,
   "nombre" : "Kevin",
   "apellido" : "Pedrosa",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1997-09-19"),
   "curso" : "Levantamiento de Procesos",
   "aptitudes" : ["Windows", "UML", "BPMN", "Intalio"]
 },
 {
   "origen" : "V",
   "cedula" : 23,
   "nombre" : "Javier",
   "apellido" : "Osorio",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1993-07-14"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Linux", "Oracle", "PostgreSQL", "MySQL", "Javascript", 
                "GIT", "HTML5", "CSS", "Python", "Java SE", "Java EE", 
                "AngularJS", "Spring", "Hibernate"]
 },
 {
   "origen" : "E",
   "cedula" : 24,
   "nombre" : "Mary",
   "apellido" : "González",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1995-11-10"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Windows", "Oracle", "MongoDB", "MySQL", "PHP",
                "Javascript", "HTML5", "CSS", "Ruby", "Java EE", 
                "Node", "AngularJS", "Symfony", "ExpressJS", "Rails"]
 },
 {
   "origen" : "E",
   "cedula" : 25,
   "nombre" : "Ana",
   "apellido" : "Luengo",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1983-12-17"),
   "curso" : "Levantamiento de Procesos",
   "aptitudes" : ["Linux", "Windows", "UML", "BPMN", "Intalio"]
 },
 {
   "origen" : "V",
   "cedula" : 26,
   "nombre" : "Leticia",
   "apellido" : "Prieto",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1989-10-07"),
   "curso" : "Levantamiento de Procesos",
   "aptitudes" : ["Linux", "BPMN", "Bonita"]
 },
 {
   "origen" : "E",
   "cedula" : 27,
   "nombre" : "Mery",
   "apellido" : "Estrada",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1976-05-20"),
   "curso" : "Administración de Base de Datos",
   "aptitudes" : ["Linux", "PostgreSQL", "MongoDB", "Apache", "Nginx", 
                "Glassfish"]
 },
 {
   "origen" : "V",
   "cedula" : 28,
   "nombre" : "Orlando",
   "apellido" : "Esparragosa",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1990-04-10"),
   "curso" : "Levantamiento de Procesos",
   "aptitudes" : ["Linux", "BPMN", "Bonita", "UML"]
 },
 {
   "origen" : "E",
   "cedula" : 31,
   "nombre" : "Rosangel",
   "apellido" : "Quiroz",
   "genero": "F",
   "fecha_nacimiento" : new ISODate("1988-07-08"),
   "curso" : "Administración de Base de Datos",
   "aptitudes" : ["Linux", "PostgreSQL", "MySQL", "Apache", "Nginx", 
                "Glassfish"]
 },
 {
   "origen" : "V",
   "cedula" : 32,
   "nombre" : "Nelson",
   "apellido" : "Prato",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1992-11-13"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Linux", "MySQL", "PHP", "Javascript", "GIT", "HTML5", "CSS", 
                "Python", "AngularJS"]
 },
 {
   "origen" : "V",
   "cedula" : 33,
   "nombre" : "Nelson",
   "apellido" : "Prato",
   "genero": "M",
   "fecha_nacimiento" : new ISODate("1992-11-13"),
   "curso" : "Desarrollo de Software",
   "aptitudes" : ["Linux", "Oracle", "PHP", "Java SE", "Javascript", "GIT", 
                "HTML5", "CSS", "Python", "AngularJS", "Symfony"]
 }
 ];

db.estudiante.insert(listaDeEstudiantes);

Ejecutando esto desde la shell de MongoDB habremos cargado 19 estudiantes más el primero cargado de forma individual, tendríamos un total de 20 estudiantes.

2.- Otra forma de cargar datos es a través de un documento javascript, empecemos por guardar en un archivo llamado cargaPuntuaciones.js el siguiente código javascript (Ver más detalle en la documentación oficial):

function cargaPuntuaciones() {

    // Al estar en el contexto de un archivo Javascript en Mongo,
    // se necesita obtener la base de datos que representa el objeto db
    db = db.getSiblingDB("curso");

    db.puntuaciones.drop();

    var tiposEjercicios = [  "interrogatorio" , 
                             "ejercicio" , 
                             "tarea" , 
                             "examen",  
                             "taller",  
                             "exposición",  
                             "laboratorio",  
                             "proyecto",  
                             "foro", 
                             "debate" ];

    var cursorEstudiantes = db.estudiante.find();

    var estudiante = null;

    var puntuacion = null;
        
    while(cursorEstudiantes.hasNext()){

        estudiante = cursorEstudiantes.next();
        if (version26Post()) {
           var cargaMasiva = db.puntuaciones.initializeUnorderedBulkOp();
           for (var i = 1 ; i <= 5 ; i++) {
               for (var j = 0 ; j < 10 ; j++) {
                   cargaMasiva.insert({
                       idEstudiante : estudiante._id ,
                       periodo : i,
                       tipo : tiposEjercicios[j] ,
                       puntuacion : 100 * Math.random()
                   });
               }
           }
           cargaMasiva.execute();
        }
        else {
            for (var i = 1 ; i <= 5 ; i++) {
                for(var j = 0 ; j < 10 ; j++) { 
                    db.puntuaciones.insert( { 					
                        idEstudiante : estudiante._id,
                        periodo : i,
                        tipo : tiposEjercicios[j],
                        puntuacion : 100 * Math.random()
                    });
                }
            }
        }
    }
}

/**
 * Indica si la versión de Mongo es mayor a la 2.6
 */
function version26Post() {
    var partesVersion = version().split( "." );
    return partesVersion[0] + partesVersion[1] >= 26;
};

cargaPuntuaciones();

Podemos ir a la terminal del sistema operativo y ejecutamos lo siguiente:

$ mongo localhost:27017/begin --shell cargaPuntuaciones.js

Ó también desde el shell de MongoDB podemos utilizar la función load para cargar los archivos js:

> load("/home/user/mongodb/scripts/cargaPuntuaciones.js")

Con esto, si ya hemos cargado los 20 estudiantes anteriormente tendremos 1000 calificaciones cargadas con las que próximamente podremos practicar los procesos de consulta.

3.- Otra forma de insertar datos en una base de datos MongoDB es haciendo uso del comando mongoimport, este nos permite importar datos a una colección de la base de datos a la que indiquemos a través de archivos en formato JSON o CSV. Más información en la documentación.

$ mongoimport –db users –collection contacts –file contacts.json

Esto se ejecutaría luego de haber ejecutado un mongoexport.

$ mongoexport –db users –collection contacts –out contacts.json

4.- También podemos hacer un restore de una base de datos MongoDB con el comando mongorestore, esto luego de hacer un backup de la base de datos con mongodump.

Este primer post de MongoDB (espero que no sea el último) tuvo el objetivo de estudiar las formas de insertar datos en MongoDB y entender más o menos la estructura con la que se almacenan los datos en esta muy funcional base de datos. Más adelante veremos la forma de consultar los datos, actualizarlos y eliminarlos.

Si recibes un warning al inicial la shell de mongo, acá puedes ver una solución

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s