SlideShare ist ein Scribd-Unternehmen logo
1 von 79
Engrandeciendo Grails
                     con MongoDB
                                Enrique Medina Montenegro
                                       @emedinam

                              Conferencia Greach 2011 - Madrid



Wednesday, November 2, 2011
Agenda
                   •      Quién soy

                   •      Por qué estoy aquí (gracias Burt)

                   •      NoSQL: qué está pasando ahí fuera

                   •      MongoDB: por dónde empiezo

                   •      Plugin MongoDB: qué puedo y qué no puedo hacer

                   •      Conclusiones, ruegos y preguntas




Wednesday, November 2, 2011
Quién soy
   •      Ingeniero en Informática (15 años de experiencia, no siempre en
          arquitecturas Java)

   •      Desarrollador con Groovy/Grails (3+ años)

   •      Creador del Observatorio de Grails y de cuestamenos.com

   •      Firme creyente y defensor del open-source

   •      Padre, liberal, autodidacta, y apasionado de la tecnología (¿geek?)



Wednesday, November 2, 2011
Por qué estoy aquí
        •      Burt Beckwith: Advanced GORM: Performance, Customization and
               Monitoring - http://www.infoq.com/presentations/GORM-Performance

        •      Mapeo tradicional de asociaciones entre clases del dominio:

                              1:1               1:M                      M:N

                   A                B      A           B             A         B
                       hasOne               hasMany &                  hasMany &
                     (belongsTo)             belongsTo                 belongsTo
                                           (bidireccional)               (dueño)
                          C ARGA PEREZOSA (LAZY LOADING)


        •      Modelo relacional normalizado: todo son ‘joins’, no duplicamos datos



Wednesday, November 2, 2011
Por qué estoy aquí
       •      ¿Dónde está el problema?
             •      hasMany genera un campo colleción de tipo Set (org.hibernate.collection.PersistentSet)
                    que asegura la unicidad de sus elementos

             •      Añadir un elemento a la colección implica que Hibernate debe cargar TODA la
                    colección para asegurarse la unicidad

             •      Aunque cambiemos a un tipo List, Hibernate debe cargar también TODA la colección
                    para asegurar el orden, aún cuando normalmente insertamos al final de la misma

             •      Se podría solucionar con el tipo Bag, pero Grails no lo soporta

             •      Y definir la carga ‘perezosa’ sólo retrasa el problema


       •      Entonces, ¿qué pasaría si trabajáramos con una colección de miles (o
              cientos de miles) de elementos? Da miedo pensarlo, ¿verdad?



Wednesday, November 2, 2011
Por qué estoy aquí
       •      Otros problemas que tenemos que conocer:

             •      Uso específico de ‘eager’ para ahorrar consultas: mucho cuidado, puede
                    ser peor el remedio que la enfermedad (muchos ‘joins’ son más lentos que
                    las consultas por separado)

             •      Caché de consulta (query cache): inútil si estás trabajando con datos
                    afectados por el tiempo (el parámetro ‘tiempo’ siempre será distinto)

             •      Caché de segundo nivel (2nd level cache): no está activa por defecto; hay
                    que saber configurarla bien o comenzarán a aparecer errores de
                    sincronización (stale data)

       •      Y la culpa de todo la tiene el DISEÑO relacional (y cuanto más normalizado,
              mucho peor...), así que ¡¡¡DESAPRENDE!!!




Wednesday, November 2, 2011
NoSQL: qué está pasando
       •      NoSQL: la palabra en boca de todo el mundo. ¿Moda pasajera o viene a
              quedarse?

       •      NoSQL = no relacional, desestructurado, escalable, distribuido, eficiente

             •      Orientada a documentos: CouchDB, MongoDB, SimpleDB

             •      Grafos: Neo4j, OrientDB, FlockDB

             •      Clave/Valor: Redis, Cassandra, Coherence, BigTable

             •      Objetual: db4o, ObjectDBm ObjectStore

       •      El reto es saber CÓMO y CUÁNDO utilizar QUÉ tipo de NoSQL



Wednesday, November 2, 2011
NoSQL: qué está pasando
       •      Veamos si podemos ayudar un poco en este caos:

            •      Orientada a documentos: Son las más ‘parecidas’ al modelo relacional,
                   y por ello las más usadas (pero pueden ser un arma de doble filo)

            •      Grafos: Verticalizan su ámbito a información gestionada mediante
                   grafos, como redes sociales

            •      Clave/Valor: Seguramente las más rápidas. Es como si en vez de SQL
                   sólo pudieras usar mapas con ‘get/put’

            •      Objetual: Se esperaba mucho de ellas, pero no terminaron de cuajar

  CONSEJO: ¿cuál es el diseño de tu modelo y la estrategia de acceso a los datos?



Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)

                                   Replicación y Alta Disponibilidad (tolerancia a fallos)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)

                                   Replicación y Alta Disponibilidad (tolerancia a fallos)

                                     Auto-Sharding (escalabilidad horizontal eficiente)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)

                                   Replicación y Alta Disponibilidad (tolerancia a fallos)

                                     Auto-Sharding (escalabilidad horizontal eficiente)

                                  Modificadores atómicos (actualizaciones rápidas in-situ)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)

                                   Replicación y Alta Disponibilidad (tolerancia a fallos)

                                     Auto-Sharding (escalabilidad horizontal eficiente)

                                  Modificadores atómicos (actualizaciones rápidas in-situ)

                                  Lenguaje enriquecido de consultas (métodos propios)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)

                                   Replicación y Alta Disponibilidad (tolerancia a fallos)

                                     Auto-Sharding (escalabilidad horizontal eficiente)

                                  Modificadores atómicos (actualizaciones rápidas in-situ)

                                  Lenguaje enriquecido de consultas (métodos propios)

                                Operaciones Map/Reduce (agregación y proceso de datos)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)

                                   Replicación y Alta Disponibilidad (tolerancia a fallos)

                                     Auto-Sharding (escalabilidad horizontal eficiente)

                                  Modificadores atómicos (actualizaciones rápidas in-situ)

                                  Lenguaje enriquecido de consultas (métodos propios)

                                Operaciones Map/Reduce (agregación y proceso de datos)

                                      GridFS (almacenamiento avanzado de ficheros)




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
     •      MongoDB (from "humongous") is a scalable, high-performance, open source, document-
            oriented database - 10gen, Inc (creadores de MongoDB)

                              Orientada a documentos (estilo JSON con esquemas dinámicos)

                              Soporte completo para indexación (optimización de búsquedas)

                                   Replicación y Alta Disponibilidad (tolerancia a fallos)

                                     Auto-Sharding (escalabilidad horizontal eficiente)

                                  Modificadores atómicos (actualizaciones rápidas in-situ)

                                  Lenguaje enriquecido de consultas (métodos propios)

                                Operaciones Map/Reduce (agregación y proceso de datos)

                                      GridFS (almacenamiento avanzado de ficheros)


                   Pero, ¡¡¡no tiene TRANSACCIONALIDAD!!! ¿Uhhh?


Wednesday, November 2, 2011
MongoDB: por dónde empiezo
      •      Llamemos a las cosas por su nombre:




      • ATENCIÓN: ‘join’ vs ‘embedding and linking’
Wednesday, November 2, 2011
MongoDB: por dónde empiezo

      •      Diseño del modelo: Embedding vs Linking

            •      Embedding --> Incrustar un documento dentro de otro.
                   Recomendado en asociaciones por identificación,
                   maestro/detalle, padre/hijo, para evitar ‘joins’, etc.

            •      Linking --> Es el homólogo al ‘join’ relacional, pero mucho
                   más optimizado (DBRef).




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
      •      Ejemplos de referencias (linking):




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
      •      Ejemplos de incrustación (embedding):
                        db.students                  db.people              db.employee

              name: ‘Jane’                  first_name: ‘Enrique’    first_name: ‘Enrique’
              address:                      last_name: ‘Medina’      last_name: ‘Medina’
                                            addresses:               age: 38
                  address: ‘123 Main St.’
                                                                     load: 2.0
                  city: ‘New York’
                                               address: ‘Calle 1’    role: ‘Manager’
                  state: ‘NY’
                                               city: ‘Elche’         start_date: 04/11/2010
                  postalCode: ‘10014’
                                               state: ‘Alicante’     contact:
              scores:                          postalCode: ‘03204’
                  for_course:                                           place: ‘Main building’
                      name: ‘Biology’                                   address: ‘123 Main St.’
                                               address: ‘Calle 2’
                      grade: 4.0                                        city: ‘New York’
                                               city: ‘Madrid’           postalCode: ‘10014’
                  for_course:                  state: ‘Madrid’          phone1: ‘900123456’
                      name: ‘English’          postalCode: ‘28080’      phone2: ‘900789873’
                      grade: 3.0




Wednesday, November 2, 2011
MongoDB: por dónde empiezo
      •      Map/Reduce, la bestia negra de NoSQL:




Wednesday, November 2, 2011
Plugins MongoDB
      •      MongoDB GORM v.1.0.0.M7 --> http://www.grails.org/plugin/mongodb

      •      Grails MongoDB v.0.5.4 --> http://www.grails.org/plugin/gorm-mongodb

      •      Alternative MongoDB GORM based on the Morphia library v.0.7.5 -->
             http://www.grails.org/plugin/mongodb-morphia

      •      MongoDB Tools v.0.1.2 --> http://www.grails.org/plugin/mongodb-tools

      •      Mongodb Multitenant v.0.2.2.6-BETA --> http://www.grails.org/plugin/mongodb-
             multitenant

      •      Spring MongoDB Datastore support for ZK v.1.1-M1 --> http://grails.org/
             plugin/zk-mongodb




Wednesday, November 2, 2011
Plugin MongoDB GORM
      •      Grails fue concebido con espíritu relacional (GORM con Hibernate)

      •      Pero, ¿y ahora que queremos usar MongoDB?

                                GORM                      MongoDB
                                hasOne                Embed / Reference
                               hasMany                Embed / Reference
                               belongsTo              Embed / Reference
                               embedded                     Embed

      CONSEJO: No dejes que Grails condicione tu diseño MongoDB (NoSQL)




Wednesday, November 2, 2011
Plugin MongoDB GORM
      •      Diseccionando el plugin nos encontramos:

           •      Integración con GORM (Spring Data - Document Stores)

           •      Uso del driver oficial Java para MongoDB

           •      Uso de la librería GMongo (API al estilo Groovy)

           •      Mapeador de BSON a tipos Groovy/Java

           •      Soporte de métodos dinámicos, criterios y consultas nominadas (pero
                  no HQL, M:N, proyecciones en criterios, y más...)

           •      TRANSACCIONALIDAD --> ¿Magia?




Wednesday, November 2, 2011
Plugin MongoDB GORM
      •      Mapeo de clases del dominio a colecciones Mongo:

                         Reference
                                                                    Embedded
                 class Person {
                     String firstName
                     String lastName

                       static hasMany = [pets:Pet]   class Person {
                 }                                       String firstName

                              o bien
                                                         String lastName
                                                         Address address
                                                         List<Address> otherAddresses
                 class Person {                          static embedded = ['address', 'otherAddresses']
                     String firstName                }
                     String lastName
                 }

                 class Pet {
                     String name
                     String breed

                       Person person
                 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
      •      Mapeo de clases del dominio a colecciones Mongo (cont.):

                          Identidad                                     WriteConcern
                  import org.bson.types.ObjectId                import com.mongodb.WriteConcern

                  class Person {                                class Person {
                      ObjectId id
                                                                    String name
                  }
                                                                    static mapping = {

                                                                        writeConcern WriteConcern.FSYNC_SAFE


                              Índices
                                                                    }

                                                                }


                class Person {
                    String name
                    static mapping = {
                        name index:true, indexAttributes: [unique:true, dropDups:true]
                    }
                }




Wednesday, November 2, 2011
Plugin MongoDB GORM
      •      Mapeo de clases del dominio a colecciones Mongo (cont.):
                              Geospacial                                Atributos dinámicos
            class Hotel {                                                  class Plant {
                String name                                                    boolean goesInPatch
                List location                                                  String name
                static mapping = {                                         }
                    location geoIndex:true,
                     indexAttributes:[min:-500, max:500]                   def p = new Plant(name:"Pineapple")
                }                                                          p['color'] = 'Yellow'
                                                                           p['hasLeaves'] = true
            }                                                              p.save()
                                                                           p = Plant.findByName("Pineapple")
            new Hotel(name:"Hilton", location:
                [lat: 40.739037, long: 73.992964]).save()                  println p['color']

           def h = Hotel.findByLocationNear([50, 60])                      println p['hasLeaves']
           assert h.name == 'Hilton'

           def box = [[40.73083, -73.99756], [40.741404,    -73.988135]]
           def h = Hotel.findByLocationWithinBox(box)

           def center = [50, 50]
           def radius = 10
           def h = Hotel.findByLocationWithinCircle([center, radius])




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Demo 1 - 1:1 / M:1 sin ‘hasOne’ ni ‘belongsTo’
               Paso 1. Crear un maestro y un detalle
               Thu Oct 27 17:46:59 [initandlisten] connection accepted from 192.168.0.102:53298 #54
               Thu Oct 27 17:47:00 [conn54] remove prueba1.maestro query: {} 20ms
               Thu Oct 27 17:47:00 [conn54] query: prueba1.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 17:47:00 [conn54] run command prueba1.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 17:47:00 [conn54] query prueba1.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 33ms
               Thu Oct 27 17:47:00 [conn54] remove prueba1.detalle query: {} 0ms
               Thu Oct 27 17:47:00 [conn54] query: prueba1.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 17:47:00 [conn54] run command prueba1.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 17:47:00 [conn54] query prueba1.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 100ms
               Thu Oct 27 17:47:00 [conn54] insert prueba1.maestro 0ms
               Thu Oct 27 17:47:00 [conn54] insert prueba1.detalle 0ms


               > db.maestro.find()
               { "_id" : ObjectId("4ea97cf4a0ee87eee9573adf"), "nombre" : "Maestro1", "version" : 0 }

               > db.detalle.find()
               { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" :
               "Detalle1", "version" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Demo 1 - 1:1 / M:1 sin ‘hasOne’ ni ‘belongsTo’
               Paso 2. Buscar un maestro e imprimir su detalle

               Thu Oct 27 17:50:47 [initandlisten] connection accepted from 192.168.0.102:53403 #55
               Thu Oct 27 17:50:47 [conn55] query: prueba1.maestro{ nombre: "Maestro1" }
               Thu Oct 27 17:50:47 [conn55] used cursor: 0x100f5c520
               Thu Oct 27 17:50:47 [conn55] query prueba1.maestro ntoreturn:1 reslen:92 nreturned:1 0ms
               Thu Oct 27 17:50:47 [conn55] query: prueba1.detalle{ maestro.$id: ObjectId('4ea97cf4a0ee87eee9573adf') }
               Thu Oct 27 17:50:47 [conn55] used cursor: 0x100f53d80
               Thu Oct 27 17:50:47 [conn55] query prueba1.detalle ntoreturn:1 reslen:141 nreturned:1 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Demo 2 - 1:1 con ‘hasOne’
               Paso 1. Crear un maestro y un detalle
               Thu Oct 27 18:14:10 [initandlisten] connection accepted from 192.168.0.102:53795 #63
               Thu Oct 27 18:14:10 [conn63] remove prueba2.maestro query: {} 0ms
               Thu Oct 27 18:14:10 [conn63] query: prueba2.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 18:14:10 [conn63] run command prueba2.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 18:14:10 [conn63] query prueba2.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 0ms
               Thu Oct 27 18:14:10 [conn63] remove prueba2.detalle query: {} 0ms
               Thu Oct 27 18:14:10 [conn63] query: prueba2.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 18:14:10 [conn63] run command prueba2.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true }
               Thu Oct 27 18:14:10 [conn63] query prueba2.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 95ms
               Thu Oct 27 18:14:10 [conn63] insert prueba2.detalle 0ms
               Thu Oct 27 18:14:10 [conn63] insert prueba2.maestro 0ms


               > db.maestro.find()
               { "_id" : ObjectId("4ea98595a0ee4f17bac48f87"), "nombre" : "Maestro2", "version" : 0 }

               > db.detalle.find()
               { "_id" : ObjectId("4ea98595a0ee4f17bac48f88"), "nombre" : "Detalle2", "detalle" : { "$ref" : "maestro", "$id" : ObjectId("4ea98595a0ee4f17bac48f87") },
               "version" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Demo 3 - 1:M con ‘hasMany’
               Paso 1. Crear un maestro y varios detalled
               Thu Oct 27 18:37:23 [conn78] insert prueba3.detalle 0ms
               Thu Oct 27 18:37:23 [conn78] insert prueba3.maestro 0ms
               Thu Oct 27 18:37:23 [conn78] update prueba3.maestro query: { _id: ObjectId('4ea988c3a0ee8ac0c9c3cab7') } update: { _id:
               ObjectId('4ea988c3a0ee8ac0c9c3cab7'), nombre: "Maestro3", version: 0, detalles: [ { $ref: "maestro", $id: ObjectId('4ea988c3a0ee8ac0c9c3cab8') },
               { $ref: "maestro", $id: ObjectId('4ea988c3a0ee8ac0c9c3cab9') }, { $ref: "maestro", $id: ObjectId('4ea988c3a0ee8ac0c9c3caba') } ] } byid 0ms

               > db.maestro.find()
               { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3cab7"), "nombre" : "Maestro3", "version" : 0, "detalles" : [
               
         {
               
         
       "$ref" : "maestro", “$id" : ObjectId("4ea988c3a0ee8ac0c9c3cab8")
               
         },
               
         {
               
         
       "$ref" : "maestro", “$id" : ObjectId("4ea988c3a0ee8ac0c9c3cab9")
               
         },
               
         {
               
         
       "$ref" : "maestro", "$id" : ObjectId("4ea988c3a0ee8ac0c9c3caba")
               
         }
               ]}
               > db.detalle.find()
               { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3cab8"), "nombre" : "Detalle3.2", "version" : 0 }
               { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3cab9"), "nombre" : "Detalle3.1", "version" : 0 }
               { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3caba"), "nombre" : "Detalle3.3", "version" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Demo 3 - 1:M con ‘hasMany’
               Paso 2. Buscar un maestro e imprimir sus detalles

               Thu Oct 27 18:40:40 [conn78] query: prueba3.maestro{ nombre: "Maestro3" }
               Thu Oct 27 18:40:40 [conn78] used cursor: 0x101d33da0
               Thu Oct 27 18:40:40 [conn78] query prueba3.maestro ntoreturn:1 reslen:236 nreturned:1 0ms
               Thu Oct 27 18:40:40 [conn78] query: prueba3.detalle{ _id: { $in: [ ObjectId('4ea988c3a0ee8ac0c9c3cab8'),
               ObjectId('4ea988c3a0ee8ac0c9c3cab9'), ObjectId('4ea988c3a0ee8ac0c9c3caba') ] } }
               Thu Oct 27 18:40:40 [conn78] used cursor: 0x101d34140
               Thu Oct 27 18:40:40 [conn78] query prueba3.detalle reslen:210 nreturned:3 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Demo 4 - 1:M con detalles embebidos
               Paso 1. Crear un maestro y varios detalles
                   Thu Oct 27 19:11:06 [conn94] insert prueba4.maestro 0ms

                   > db.maestro.find()
                   { "_id" : ObjectId("4ea990aaa0ee155609d17314"), "detalles" : [
                   
       {
                   
       
      "nombre" : "Detalle4.1", "_embeddedClassName" : "prueba4.Detalle"
                   
       },
                   
       {
                   
       
      "nombre" : "Detalle4.2", "_embeddedClassName" : "prueba4.Detalle"
                   
       },
                   
       {
                   
       
      "nombre" : "Detalle4.3", "_embeddedClassName" : "prueba4.Detalle"
                   
       }
                   ], "nombre" : "Maestro4", "version" : 0 }

                   > db.detalle.find()
                   (No hay resultados porque ‘detalle’ no tiene entidad propia, sino que es un documento embebido en ‘maestro’)




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Demo 4 - 1:M con detalles embebidos
               Paso 2. Buscar un maestro e imprimir sus detalles

                 Thu Oct 27 19:12:09 [conn95] query: prueba4.maestro{ nombre: "Maestro4" }
                 Thu Oct 27 19:12:09 [conn95] used cursor: 0x100f4a9e0
                 Thu Oct 27 19:12:09 [conn95] query prueba4.maestro ntoreturn:1 reslen:320 nreturned:1 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      De nuevo la pregunta del millón, ¿embedded o reference?

             •      Depende del dominio de tu aplicación

             •      Para 1:M opta en realidad por un M:1
                                <1>.get<M>() { <M>.findAllBy<1>(this) }

             •      Usa embedded cuando la entidad ‘embebida’ carece de identidad
                    propia fuera de su ‘contenedor’

             •      Pero si usas embedded, Grails tiene sus limitaciones :-(

             •      Trees --> http://www.mongodb.org/display/DOCS/Trees+in
                    +MongoDB


Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 1 - Indexación de propiedades embebidas




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 1 - Indexación de propiedades embebidas




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 1 - Indexación de propiedades embebidas




                              > db.system.indexes.find()
                              { "name" : "_id_", "ns" : "detalle", "key" : { "_id" : 1 }, "v" : 0 }
                              { "name" : "nombre_1", "ns" : "detalle", "key" : { "nombre" : 1 }, "v" : 0 }
                              { "name" : "_id_", "ns" : "maestro", "key" : { "_id" : 1 }, "v" : 0 }
                              { "name" : "nombre_1", "ns" : "maestro", "key" : { "nombre" : 1 }, "v" : 0 }
                              { "name" : "detalles.nombre_1", "ns" : "maestro", "key" : { "detalles.nombre" : 1 }, "v" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 1 - Indexación de propiedades embebidas (cont.)




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 1 - Indexación de propiedades embebidas (cont.)
               > db.maestro.find({"detalles.nombre": "Detalle4.2"})
               { "_id" : ObjectId("4ea990dfa0ee155609d17315"),
               "detalles" : [
               
      {
               
      
       "nombre" : "Detalle4.1",
               
      
       "_embeddedClassName" : "Detalle"
               
      },
               
      {
               
      
       "nombre" : "Detalle4.2",
               
      
       "_embeddedClassName" : "Detalle"
               
      },
               
      {
               
      
       "nombre" : "Detalle4.3",
               
      
       "_embeddedClassName" : "Detalle"
               
      }
               ], "nombre" : "Maestro4", "version" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 1 - Indexación de propiedades embebidas (cont.)
               > db.maestro.find({"detalles.nombre": "Detalle4.2"})   > db.maestro.find({"detalles.nombre": "Detalle4.2"}).explain()
               { "_id" : ObjectId("4ea990dfa0ee155609d17315"),       {
               "detalles" : [                                        
     "cursor" : "BtreeCursor detalles.nombre_1",
               
      {                                              
     "nscanned" : 1,
               
      
       "nombre" : "Detalle4.1",               
     "nscannedObjects" : 1,
               
      
       "_embeddedClassName" : "Detalle"       
     "n" : 1,
               
      },                                             
     "millis" : 24,
               
      {                                              
     "nYields" : 0,
               
      
       "nombre" : "Detalle4.2",               
     "nChunkSkips" : 0,
               
      
       "_embeddedClassName" : "Detalle"       
     "isMultiKey" : true,
               
      },                                             
     "indexOnly" : false,
               
      {                                              
     "indexBounds" : {
               
      
       "nombre" : "Detalle4.3",               
     
       "detalles.nombre" : [
               
      
       "_embeddedClassName" : "Detalle"       
     
       
      [
               
      }                                              
     
       
      
     "Detalle4.2", “Detalle4.2"
               ], "nombre" : "Maestro4", "version" : 0 }             
     
       
      ]
                                                                     
     
       ]
                                                                     
     }
                                                                     }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (DBRef)




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (DBRef)




                                          > db.system.indexes.find()
                                          { "name" : "_id_", "ns" : "detalle", "key" : { "_id" : 1 }, "v" : 0 }
                                          { "name" : "nombre_1", "ns" : "detalle", "key" : { "nombre" : 1 }, "v" : 0 }
                                          { "name" : "_id_", "ns" : "maestro", "key" : { "_id" : 1 }, "v" : 0 }
                                          { "name" : "nombre_1", "ns" : "maestro", "key" : { "nombre" : 1 }, "v" : 0 }
                                          { "name" : "maestro_1", "ns" : "detalle", "key" : { "maestro" : 1 }, "v" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)




                Wed Nov 2 12:58:44 [conn1] query: detalle{ maestro.$id: ObjectId('4ea97cf4a0ee87eee9573adf') }
                Wed Nov 2 12:58:44 [conn1] used cursor: 0x101e02ac0
                Wed Nov 2 12:58:44 [conn1] query detalle reslen:141 nreturned:1 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)
                > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"})
                {
                   "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"),
                   "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") },
                   "nombre" : "Detalle1", "version" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)
                > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"})
                {
                   "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"),
                   "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") },
                   "nombre" : "Detalle1", "version" : 0 }


                > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}).explain()
                   {
                   
         "cursor" : "BasicCursor",
                   
         "nscanned" : 1,
                   
         "nscannedObjects" : 1,
                   
         "n" : 1,
                   
         "millis" : 0,
                   
         "nYields" : 0,
                   
         "nChunkSkips" : 0,
                   
         "isMultiKey" : false,
                   
         "indexOnly" : false,
                   
         "indexBounds" : {}
                   }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)
                > db.detalle.find({'maestro': new DBRef('detalle', ObjectId("4ea97cf4a0ee87eee9573adf"))})
                {
                   "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"),
                   "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") },
                   "nombre" : "Detalle1", "version" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)
                > db.detalle.find({'maestro': new DBRef('detalle', ObjectId("4ea97cf4a0ee87eee9573adf"))})
                {
                   "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"),
                   "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") },
                   "nombre" : "Detalle1", "version" : 0 }

                > db.detalle.find({'maestro': new DBRef('detalle', ObjectId("4ea97cf4a0ee87eee9573adf"))}).explain()
                   {
                   
         "cursor" : "BtreeCursor maestro_1",
                   
         "nscanned" : 1, "nscannedObjects" : 1,
                   
         "n" : 1, "millis" : 0,
                   
         "indexBounds" : {
                       
     
       "maestro" : [ [
                   
         
       
       
      {
                   
         
       
       
      
  "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf")
                   
         
       
       
      },
                   
         
       
       
      {
                   
         
       
       
      
  "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf")
                   
         
       
       
      }
                   
         
       
       ]]}}




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (DBRef)




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (DBRef)




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (DBRef)




                              > db.system.indexes.find()
                              { "name" : "_id_", "ns" : "detalle", "key" : { "_id" : 1 }, "v" : 0 }
                              { "name" : "nombre_1", "ns" : "detalle", "key" : { "nombre" : 1 }, "v" : 0 }
                              { "name" : "_id_", "ns" : "maestro", "key" : { "_id" : 1 }, "v" : 0 }
                              { "name" : "nombre_1", "ns" : "maestro", "key" : { "nombre" : 1 }, "v" : 0 }
                              { "name" : "maestro.$id_1", "ns" : "detalle", "key" : { "maestro.$id" : 1 }, "v" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)
                > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"})
                {
                   "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"),
                   "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") },
                   "nombre" : "Detalle1", "version" : 0 }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 2 - Indexación de referencias (cont.)
                > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"})
                {
                   "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"),
                   "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") },
                   "nombre" : "Detalle1", "version" : 0 }


                > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}).explain()
                   {
                   
         "cursor" : "BtreeCursor maestro.$id_1",
                   
         "nscanned" : 1, "nscannedObjects" : 1,
                   
         "n" : 1, "millis" : 0,
                   
         "indexBounds" : {
                   
         
       "maestro.$id" : [
                   
         
       
       [
                   
         
       
       
      ObjectId("4ea97cf4a0ee87eee9573adf"), ObjectId("4ea97cf4a0ee87eee9573adf")
                   
         
       
       ]
                   
         
       ]
                   
         }
                   }




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 3 - Búsquedas sobre propiedades embebidas




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 3 - Búsquedas sobre propiedades embebidas



                          Thu Oct 27 20:51:23 [conn99] query: maestro{ detalles.nombre: "Detalle4.2" }
                          Thu Oct 27 20:51:23 [conn99] used cursor: 0x101d108d0
                          Thu Oct 27 20:51:23 [conn99] query maestro reslen:320 nreturned:1 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 3 - Búsquedas sobre propiedades embebidas



                          Thu Oct 27 20:51:23 [conn99] query: maestro{ detalles.nombre: "Detalle4.2" }
                          Thu Oct 27 20:51:23 [conn99] used cursor: 0x101d108d0
                          Thu Oct 27 20:51:23 [conn99] query maestro reslen:320 nreturned:1 0ms

                                           Pero luego, hay que obtener el detalle en cuestión...




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 3 - Búsquedas sobre propiedades embebidas



                          Thu Oct 27 20:51:23 [conn99] query: maestro{ detalles.nombre: "Detalle4.2" }
                          Thu Oct 27 20:51:23 [conn99] used cursor: 0x101d108d0
                          Thu Oct 27 20:51:23 [conn99] query maestro reslen:320 nreturned:1 0ms

                                           Pero luego, hay que obtener el detalle en cuestión...




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 4 - Búsquedas embebidas con múltiples coincidencias




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 4 - Búsquedas embebidas con múltiples coincidencias




                          Thu Oct 27 20:53:45 [conn99] query: factura{ articulos.descripcion: "~/(i)iPhone/" }
                          Thu Oct 27 20:53:45 [conn99] used cursor: 0x101f108e1
                          Thu Oct 27 20:53:45 [conn99] query factura reslen:932 nreturned:1 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 4 - Búsquedas embebidas con múltiples coincidencias




                          Thu Oct 27 20:53:45 [conn99] query: factura{ articulos.descripcion: "~/(i)iPhone/" }
                          Thu Oct 27 20:53:45 [conn99] used cursor: 0x101f108e1
                          Thu Oct 27 20:53:45 [conn99] query factura reslen:932 nreturned:1 0ms

                               Pero como puede haber varias líneas que coincida la descripción de artículo...




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 4 - Búsquedas embebidas con múltiples coincidencias




                          Thu Oct 27 20:53:45 [conn99] query: factura{ articulos.descripcion: "~/(i)iPhone/" }
                          Thu Oct 27 20:53:45 [conn99] used cursor: 0x101f108e1
                          Thu Oct 27 20:53:45 [conn99] query factura reslen:932 nreturned:1 0ms

                               Pero como puede haber varias líneas que coincida la descripción de artículo...




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 5 - Búsquedas por existencia en campos embebidos
                                  (e.j. facturas sin cobros)




Wednesday, November 2, 2011
Plugin MongoDB GORM
        •      Limitación 5 - Búsquedas por existencia en campos embebidos
                                  (e.j. facturas sin cobros)




                              Thu Oct 27 20:55:45 [conn99] query: factura{ cobros: { $exists: false } }
                              Thu Oct 27 20:55:45 [conn99] used cursor: 0x2314508a1
                              Thu Oct 27 20:55:45 [conn99] query factura reslen:320 nreturned:15 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 6 - Búsquedas con $where (expresiones Javascript)




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 6 - Búsquedas con $where (expresiones Javascript)




                              Thu Oct 27 21:55:45 [conn99] query: factura{ $where: “this.total > 1000” }
                              Thu Oct 27 21:55:45 [conn99] used cursor: 0x101d42e20
                              Thu Oct 27 21:55:45 [conn99] query factura reslen:92 nreturned:13 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 7 - Búsquedas ‘low API’ en referencias (sin plugin)




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 7 - Búsquedas ‘low API’ en referencias (sin plugin)




            Thu Oct 27 21:56:23 [conn99] query: detalle{ maestro: { $ref: “detalle”, $id: ObjectId('4ea97cf4a0ee87eee9573adf') } }
            Thu Oct 27 21:56:23 [conn99] used cursor: 0x10302cba0
            Thu Oct 27 21:56:23 [conn99] query factura reslen:141 nreturned:1 0ms




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 8.1 - Cálculos mediante Map/Reduce (servidor)




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 8.1 - Cálculos mediante Map/Reduce (servidor)




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 8.2 - Cálculos mediante agrupación (db.group)




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 8.2 - Cálculos mediante agrupación (db.group)




                   [[odd:true, count:99.0], [even:true, count:56.0]]


Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 8.3 - Procedimientos almacenados (db.eval)
                              function my_erase() {
                                db.things.find().forEach( function(obj) {
                                               delete obj.foo;
                                               db.things.save(obj);
                                             } );
                              }

                              my_erase();




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 8.3 - Procedimientos almacenados (db.eval)
                              function my_erase() {
                                db.things.find().forEach( function(obj) {
                                               delete obj.foo;
                                               db.things.save(obj);
                                             } );
                              }

                              my_erase();
                                  Para evitar cargar en cliente el contenido entero de la colección...




Wednesday, November 2, 2011
Plugin MongoDB GORM

        •      Limitación 8.3 - Procedimientos almacenados (db.eval)
                              function my_erase() {
                                db.things.find().forEach( function(obj) {
                                               delete obj.foo;
                                               db.things.save(obj);
                                             } );
                              }

                              my_erase();
                                  Para evitar cargar en cliente el contenido entero de la colección...




                                                       db.eval(my_erase);




Wednesday, November 2, 2011
Conclusiones

      •      Lecciones aprendidas en mi experiencia de desarrollo:

           •      Piensa muy bien el diseño de tu repositorio MongoDB

           •      Si embebes colecciones, prevé si necesitarás identificar los elementos

           •      Aprende GMongo: se convertirá en tu mejor aliado

           •      No te dejes influenciar por lo que ofrece o no ofrece el plugin

           •      MongoDB no es sólo CRUD: investiga, aprende, disfruta




Wednesday, November 2, 2011
Preguntas
                                  &
                              Respuestas

Wednesday, November 2, 2011

Weitere ähnliche Inhalte

Ähnlich wie Creating Productive Workshops in Scary Situations

Ähnlich wie Creating Productive Workshops in Scary Situations (20)

Introducción mongodb y desarrollo
Introducción mongodb y desarrolloIntroducción mongodb y desarrollo
Introducción mongodb y desarrollo
 
Mongo bd michael landeo vargas
Mongo bd michael landeo vargasMongo bd michael landeo vargas
Mongo bd michael landeo vargas
 
Introduccón a Mongodb
Introduccón a MongodbIntroduccón a Mongodb
Introduccón a Mongodb
 
Hadoop barcamp 2011
Hadoop   barcamp 2011Hadoop   barcamp 2011
Hadoop barcamp 2011
 
Greach 2011 - Engrandeciendo Grails con Mongo DB
Greach 2011 - Engrandeciendo Grails con Mongo DBGreach 2011 - Engrandeciendo Grails con Mongo DB
Greach 2011 - Engrandeciendo Grails con Mongo DB
 
Lunch & Learn: El poder de las NoSQL con mongoDB
Lunch & Learn:  El poder de las NoSQL con mongoDBLunch & Learn:  El poder de las NoSQL con mongoDB
Lunch & Learn: El poder de las NoSQL con mongoDB
 
MongoDB
MongoDBMongoDB
MongoDB
 
Big table por Matias tesoriero
Big table por Matias tesorieroBig table por Matias tesoriero
Big table por Matias tesoriero
 
Panorama BigData (OpenExpo2017)
Panorama BigData (OpenExpo2017)Panorama BigData (OpenExpo2017)
Panorama BigData (OpenExpo2017)
 
Video_MartinFowler.pptx
Video_MartinFowler.pptxVideo_MartinFowler.pptx
Video_MartinFowler.pptx
 
Video_MartinFowler.pptx
Video_MartinFowler.pptxVideo_MartinFowler.pptx
Video_MartinFowler.pptx
 
¿que es mongodb?
¿que es mongodb?¿que es mongodb?
¿que es mongodb?
 
Base de Datos
Base de DatosBase de Datos
Base de Datos
 
MongoDB
MongoDBMongoDB
MongoDB
 
Bases de datos NoSQL orientadas a documentos
Bases de datos NoSQL orientadas a documentosBases de datos NoSQL orientadas a documentos
Bases de datos NoSQL orientadas a documentos
 
Base de datos
Base de datosBase de datos
Base de datos
 
Semana 3 Mongodb
Semana 3   MongodbSemana 3   Mongodb
Semana 3 Mongodb
 
Mongo db course introduction
Mongo db course   introductionMongo db course   introduction
Mongo db course introduction
 
Smalltalk intro I
Smalltalk intro ISmalltalk intro I
Smalltalk intro I
 
MongoDB (Conceptos Básicos) - Junio 2010
MongoDB (Conceptos Básicos) - Junio 2010MongoDB (Conceptos Básicos) - Junio 2010
MongoDB (Conceptos Básicos) - Junio 2010
 

Mehr von Effective

User Testing: Adapt to Fit Your Needs
User Testing: Adapt to Fit Your NeedsUser Testing: Adapt to Fit Your Needs
User Testing: Adapt to Fit Your NeedsEffective
 
Death of a Design: 5 Stages of Grief
Death of a Design: 5 Stages of GriefDeath of a Design: 5 Stages of Grief
Death of a Design: 5 Stages of GriefEffective
 
UX Design Process 101: Where to start with UX
UX Design Process 101: Where to start with UXUX Design Process 101: Where to start with UX
UX Design Process 101: Where to start with UXEffective
 
Give Them What They Want: Discovering Customer Need with Wearable Technology
Give Them What They Want: Discovering Customer Need with Wearable TechnologyGive Them What They Want: Discovering Customer Need with Wearable Technology
Give Them What They Want: Discovering Customer Need with Wearable TechnologyEffective
 
Common Innovation Myths (World Usability Day)
Common Innovation Myths (World Usability Day)Common Innovation Myths (World Usability Day)
Common Innovation Myths (World Usability Day)Effective
 
Introduction to UX
Introduction to UXIntroduction to UX
Introduction to UXEffective
 
2016 SXSW Measures for Justice Panel Picker Presentation
2016 SXSW Measures for Justice Panel Picker Presentation2016 SXSW Measures for Justice Panel Picker Presentation
2016 SXSW Measures for Justice Panel Picker PresentationEffective
 
Water For People UX Awards Submission
Water For People UX Awards SubmissionWater For People UX Awards Submission
Water For People UX Awards SubmissionEffective
 
Getting into the Game: How EA Put User Research into Practice
Getting into the Game: How EA Put User Research into PracticeGetting into the Game: How EA Put User Research into Practice
Getting into the Game: How EA Put User Research into PracticeEffective
 
Scottrade and Understanding the Customer Journey: When Segmentation Isn’t Enough
Scottrade and Understanding the Customer Journey: When Segmentation Isn’t EnoughScottrade and Understanding the Customer Journey: When Segmentation Isn’t Enough
Scottrade and Understanding the Customer Journey: When Segmentation Isn’t EnoughEffective
 
A Blended Space for Heritage Storytelling
A Blended Space for Heritage StorytellingA Blended Space for Heritage Storytelling
A Blended Space for Heritage StorytellingEffective
 
Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...
Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...
Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...Effective
 
Mobile Website Design: Responsive, Adaptive or Both?
Mobile Website Design: Responsive, Adaptive or Both?Mobile Website Design: Responsive, Adaptive or Both?
Mobile Website Design: Responsive, Adaptive or Both?Effective
 
Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...
Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...
Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...Effective
 
Liferay and Water For People: From Data to Information
Liferay and Water For People: From Data to InformationLiferay and Water For People: From Data to Information
Liferay and Water For People: From Data to InformationEffective
 
The Rules of UX - Enterprise 2.0
The Rules of UX - Enterprise 2.0The Rules of UX - Enterprise 2.0
The Rules of UX - Enterprise 2.0Effective
 
Making Mobile Meaningful NY 2013
Making Mobile Meaningful NY 2013Making Mobile Meaningful NY 2013
Making Mobile Meaningful NY 2013Effective
 
Experience Driven Development - Future Insights Live 2013
Experience Driven Development - Future Insights Live 2013Experience Driven Development - Future Insights Live 2013
Experience Driven Development - Future Insights Live 2013Effective
 
SXSW 2013 Daily Recap - Sunday GoodxGlobal
SXSW 2013 Daily Recap - Sunday GoodxGlobalSXSW 2013 Daily Recap - Sunday GoodxGlobal
SXSW 2013 Daily Recap - Sunday GoodxGlobalEffective
 
The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...
The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...
The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...Effective
 

Mehr von Effective (20)

User Testing: Adapt to Fit Your Needs
User Testing: Adapt to Fit Your NeedsUser Testing: Adapt to Fit Your Needs
User Testing: Adapt to Fit Your Needs
 
Death of a Design: 5 Stages of Grief
Death of a Design: 5 Stages of GriefDeath of a Design: 5 Stages of Grief
Death of a Design: 5 Stages of Grief
 
UX Design Process 101: Where to start with UX
UX Design Process 101: Where to start with UXUX Design Process 101: Where to start with UX
UX Design Process 101: Where to start with UX
 
Give Them What They Want: Discovering Customer Need with Wearable Technology
Give Them What They Want: Discovering Customer Need with Wearable TechnologyGive Them What They Want: Discovering Customer Need with Wearable Technology
Give Them What They Want: Discovering Customer Need with Wearable Technology
 
Common Innovation Myths (World Usability Day)
Common Innovation Myths (World Usability Day)Common Innovation Myths (World Usability Day)
Common Innovation Myths (World Usability Day)
 
Introduction to UX
Introduction to UXIntroduction to UX
Introduction to UX
 
2016 SXSW Measures for Justice Panel Picker Presentation
2016 SXSW Measures for Justice Panel Picker Presentation2016 SXSW Measures for Justice Panel Picker Presentation
2016 SXSW Measures for Justice Panel Picker Presentation
 
Water For People UX Awards Submission
Water For People UX Awards SubmissionWater For People UX Awards Submission
Water For People UX Awards Submission
 
Getting into the Game: How EA Put User Research into Practice
Getting into the Game: How EA Put User Research into PracticeGetting into the Game: How EA Put User Research into Practice
Getting into the Game: How EA Put User Research into Practice
 
Scottrade and Understanding the Customer Journey: When Segmentation Isn’t Enough
Scottrade and Understanding the Customer Journey: When Segmentation Isn’t EnoughScottrade and Understanding the Customer Journey: When Segmentation Isn’t Enough
Scottrade and Understanding the Customer Journey: When Segmentation Isn’t Enough
 
A Blended Space for Heritage Storytelling
A Blended Space for Heritage StorytellingA Blended Space for Heritage Storytelling
A Blended Space for Heritage Storytelling
 
Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...
Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...
Using Behavioral Modeling to Engage Customers Throughout the Decision-Making ...
 
Mobile Website Design: Responsive, Adaptive or Both?
Mobile Website Design: Responsive, Adaptive or Both?Mobile Website Design: Responsive, Adaptive or Both?
Mobile Website Design: Responsive, Adaptive or Both?
 
Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...
Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...
Integrated Thinking: The Answer to Enterprise IT’s Perpetual Struggle - Forre...
 
Liferay and Water For People: From Data to Information
Liferay and Water For People: From Data to InformationLiferay and Water For People: From Data to Information
Liferay and Water For People: From Data to Information
 
The Rules of UX - Enterprise 2.0
The Rules of UX - Enterprise 2.0The Rules of UX - Enterprise 2.0
The Rules of UX - Enterprise 2.0
 
Making Mobile Meaningful NY 2013
Making Mobile Meaningful NY 2013Making Mobile Meaningful NY 2013
Making Mobile Meaningful NY 2013
 
Experience Driven Development - Future Insights Live 2013
Experience Driven Development - Future Insights Live 2013Experience Driven Development - Future Insights Live 2013
Experience Driven Development - Future Insights Live 2013
 
SXSW 2013 Daily Recap - Sunday GoodxGlobal
SXSW 2013 Daily Recap - Sunday GoodxGlobalSXSW 2013 Daily Recap - Sunday GoodxGlobal
SXSW 2013 Daily Recap - Sunday GoodxGlobal
 
The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...
The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...
The Human Interface: Making UX An Integral Part of Your Technology Buying Dec...
 

Kürzlich hochgeladen

Hernandez_Hernandez_Practica web de la sesion 11.pptx
Hernandez_Hernandez_Practica web de la sesion 11.pptxHernandez_Hernandez_Practica web de la sesion 11.pptx
Hernandez_Hernandez_Practica web de la sesion 11.pptxJOSEMANUELHERNANDEZH11
 
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptxGoogle-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptxAlexander López
 
Explorando la historia y funcionamiento de la memoria ram
Explorando la historia y funcionamiento de la memoria ramExplorando la historia y funcionamiento de la memoria ram
Explorando la historia y funcionamiento de la memoria ramDIDIERFERNANDOGUERRE
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx241522327
 
Excel (1) tecnologia.pdf trabajo Excel taller
Excel  (1) tecnologia.pdf trabajo Excel tallerExcel  (1) tecnologia.pdf trabajo Excel taller
Excel (1) tecnologia.pdf trabajo Excel tallerValentinaTabares11
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.241514949
 
TEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.ppt
TEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.pptTEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.ppt
TEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.pptJavierHerrera662252
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx241523733
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELmaryfer27m
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxJOSEFERNANDOARENASCA
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxazmysanros90
 
AREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPO
AREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPOAREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPO
AREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPOnarvaezisabella21
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfSergioMendoza354770
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxaylincamaho
 
Tecnologias Starlink para el mundo tec.pptx
Tecnologias Starlink para el mundo tec.pptxTecnologias Starlink para el mundo tec.pptx
Tecnologias Starlink para el mundo tec.pptxGESTECPERUSAC
 
La Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdfLa Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdfjeondanny1997
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptMiguelAtencio10
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA241531640
 
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptxEl_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptxAlexander López
 
Segunda ley de la termodinámica TERMODINAMICA.pptx
Segunda ley de la termodinámica TERMODINAMICA.pptxSegunda ley de la termodinámica TERMODINAMICA.pptx
Segunda ley de la termodinámica TERMODINAMICA.pptxMariaBurgos55
 

Kürzlich hochgeladen (20)

Hernandez_Hernandez_Practica web de la sesion 11.pptx
Hernandez_Hernandez_Practica web de la sesion 11.pptxHernandez_Hernandez_Practica web de la sesion 11.pptx
Hernandez_Hernandez_Practica web de la sesion 11.pptx
 
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptxGoogle-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
 
Explorando la historia y funcionamiento de la memoria ram
Explorando la historia y funcionamiento de la memoria ramExplorando la historia y funcionamiento de la memoria ram
Explorando la historia y funcionamiento de la memoria ram
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx
 
Excel (1) tecnologia.pdf trabajo Excel taller
Excel  (1) tecnologia.pdf trabajo Excel tallerExcel  (1) tecnologia.pdf trabajo Excel taller
Excel (1) tecnologia.pdf trabajo Excel taller
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.
 
TEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.ppt
TEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.pptTEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.ppt
TEMA 2 PROTOCOLO DE EXTRACCION VEHICULAR.ppt
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFEL
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptx
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptx
 
AREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPO
AREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPOAREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPO
AREA TECNOLOGIA E INFORMATICA TRABAJO EN EQUIPO
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
 
Tecnologias Starlink para el mundo tec.pptx
Tecnologias Starlink para el mundo tec.pptxTecnologias Starlink para el mundo tec.pptx
Tecnologias Starlink para el mundo tec.pptx
 
La Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdfLa Electricidad Y La Electrónica Trabajo Tecnología.pdf
La Electricidad Y La Electrónica Trabajo Tecnología.pdf
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.ppt
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
 
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptxEl_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
 
Segunda ley de la termodinámica TERMODINAMICA.pptx
Segunda ley de la termodinámica TERMODINAMICA.pptxSegunda ley de la termodinámica TERMODINAMICA.pptx
Segunda ley de la termodinámica TERMODINAMICA.pptx
 

Creating Productive Workshops in Scary Situations

  • 1. Engrandeciendo Grails con MongoDB Enrique Medina Montenegro @emedinam Conferencia Greach 2011 - Madrid Wednesday, November 2, 2011
  • 2. Agenda • Quién soy • Por qué estoy aquí (gracias Burt) • NoSQL: qué está pasando ahí fuera • MongoDB: por dónde empiezo • Plugin MongoDB: qué puedo y qué no puedo hacer • Conclusiones, ruegos y preguntas Wednesday, November 2, 2011
  • 3. Quién soy • Ingeniero en Informática (15 años de experiencia, no siempre en arquitecturas Java) • Desarrollador con Groovy/Grails (3+ años) • Creador del Observatorio de Grails y de cuestamenos.com • Firme creyente y defensor del open-source • Padre, liberal, autodidacta, y apasionado de la tecnología (¿geek?) Wednesday, November 2, 2011
  • 4. Por qué estoy aquí • Burt Beckwith: Advanced GORM: Performance, Customization and Monitoring - http://www.infoq.com/presentations/GORM-Performance • Mapeo tradicional de asociaciones entre clases del dominio: 1:1 1:M M:N A B A B A B hasOne hasMany & hasMany & (belongsTo) belongsTo belongsTo (bidireccional) (dueño) C ARGA PEREZOSA (LAZY LOADING) • Modelo relacional normalizado: todo son ‘joins’, no duplicamos datos Wednesday, November 2, 2011
  • 5. Por qué estoy aquí • ¿Dónde está el problema? • hasMany genera un campo colleción de tipo Set (org.hibernate.collection.PersistentSet) que asegura la unicidad de sus elementos • Añadir un elemento a la colección implica que Hibernate debe cargar TODA la colección para asegurarse la unicidad • Aunque cambiemos a un tipo List, Hibernate debe cargar también TODA la colección para asegurar el orden, aún cuando normalmente insertamos al final de la misma • Se podría solucionar con el tipo Bag, pero Grails no lo soporta • Y definir la carga ‘perezosa’ sólo retrasa el problema • Entonces, ¿qué pasaría si trabajáramos con una colección de miles (o cientos de miles) de elementos? Da miedo pensarlo, ¿verdad? Wednesday, November 2, 2011
  • 6. Por qué estoy aquí • Otros problemas que tenemos que conocer: • Uso específico de ‘eager’ para ahorrar consultas: mucho cuidado, puede ser peor el remedio que la enfermedad (muchos ‘joins’ son más lentos que las consultas por separado) • Caché de consulta (query cache): inútil si estás trabajando con datos afectados por el tiempo (el parámetro ‘tiempo’ siempre será distinto) • Caché de segundo nivel (2nd level cache): no está activa por defecto; hay que saber configurarla bien o comenzarán a aparecer errores de sincronización (stale data) • Y la culpa de todo la tiene el DISEÑO relacional (y cuanto más normalizado, mucho peor...), así que ¡¡¡DESAPRENDE!!! Wednesday, November 2, 2011
  • 7. NoSQL: qué está pasando • NoSQL: la palabra en boca de todo el mundo. ¿Moda pasajera o viene a quedarse? • NoSQL = no relacional, desestructurado, escalable, distribuido, eficiente • Orientada a documentos: CouchDB, MongoDB, SimpleDB • Grafos: Neo4j, OrientDB, FlockDB • Clave/Valor: Redis, Cassandra, Coherence, BigTable • Objetual: db4o, ObjectDBm ObjectStore • El reto es saber CÓMO y CUÁNDO utilizar QUÉ tipo de NoSQL Wednesday, November 2, 2011
  • 8. NoSQL: qué está pasando • Veamos si podemos ayudar un poco en este caos: • Orientada a documentos: Son las más ‘parecidas’ al modelo relacional, y por ello las más usadas (pero pueden ser un arma de doble filo) • Grafos: Verticalizan su ámbito a información gestionada mediante grafos, como redes sociales • Clave/Valor: Seguramente las más rápidas. Es como si en vez de SQL sólo pudieras usar mapas con ‘get/put’ • Objetual: Se esperaba mucho de ellas, pero no terminaron de cuajar CONSEJO: ¿cuál es el diseño de tu modelo y la estrategia de acceso a los datos? Wednesday, November 2, 2011
  • 9. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Wednesday, November 2, 2011
  • 10. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Wednesday, November 2, 2011
  • 11. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Wednesday, November 2, 2011
  • 12. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Replicación y Alta Disponibilidad (tolerancia a fallos) Wednesday, November 2, 2011
  • 13. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Replicación y Alta Disponibilidad (tolerancia a fallos) Auto-Sharding (escalabilidad horizontal eficiente) Wednesday, November 2, 2011
  • 14. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Replicación y Alta Disponibilidad (tolerancia a fallos) Auto-Sharding (escalabilidad horizontal eficiente) Modificadores atómicos (actualizaciones rápidas in-situ) Wednesday, November 2, 2011
  • 15. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Replicación y Alta Disponibilidad (tolerancia a fallos) Auto-Sharding (escalabilidad horizontal eficiente) Modificadores atómicos (actualizaciones rápidas in-situ) Lenguaje enriquecido de consultas (métodos propios) Wednesday, November 2, 2011
  • 16. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Replicación y Alta Disponibilidad (tolerancia a fallos) Auto-Sharding (escalabilidad horizontal eficiente) Modificadores atómicos (actualizaciones rápidas in-situ) Lenguaje enriquecido de consultas (métodos propios) Operaciones Map/Reduce (agregación y proceso de datos) Wednesday, November 2, 2011
  • 17. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Replicación y Alta Disponibilidad (tolerancia a fallos) Auto-Sharding (escalabilidad horizontal eficiente) Modificadores atómicos (actualizaciones rápidas in-situ) Lenguaje enriquecido de consultas (métodos propios) Operaciones Map/Reduce (agregación y proceso de datos) GridFS (almacenamiento avanzado de ficheros) Wednesday, November 2, 2011
  • 18. MongoDB: por dónde empiezo • MongoDB (from "humongous") is a scalable, high-performance, open source, document- oriented database - 10gen, Inc (creadores de MongoDB) Orientada a documentos (estilo JSON con esquemas dinámicos) Soporte completo para indexación (optimización de búsquedas) Replicación y Alta Disponibilidad (tolerancia a fallos) Auto-Sharding (escalabilidad horizontal eficiente) Modificadores atómicos (actualizaciones rápidas in-situ) Lenguaje enriquecido de consultas (métodos propios) Operaciones Map/Reduce (agregación y proceso de datos) GridFS (almacenamiento avanzado de ficheros) Pero, ¡¡¡no tiene TRANSACCIONALIDAD!!! ¿Uhhh? Wednesday, November 2, 2011
  • 19. MongoDB: por dónde empiezo • Llamemos a las cosas por su nombre: • ATENCIÓN: ‘join’ vs ‘embedding and linking’ Wednesday, November 2, 2011
  • 20. MongoDB: por dónde empiezo • Diseño del modelo: Embedding vs Linking • Embedding --> Incrustar un documento dentro de otro. Recomendado en asociaciones por identificación, maestro/detalle, padre/hijo, para evitar ‘joins’, etc. • Linking --> Es el homólogo al ‘join’ relacional, pero mucho más optimizado (DBRef). Wednesday, November 2, 2011
  • 21. MongoDB: por dónde empiezo • Ejemplos de referencias (linking): Wednesday, November 2, 2011
  • 22. MongoDB: por dónde empiezo • Ejemplos de incrustación (embedding): db.students db.people db.employee name: ‘Jane’ first_name: ‘Enrique’ first_name: ‘Enrique’ address: last_name: ‘Medina’ last_name: ‘Medina’ addresses: age: 38 address: ‘123 Main St.’ load: 2.0 city: ‘New York’ address: ‘Calle 1’ role: ‘Manager’ state: ‘NY’ city: ‘Elche’ start_date: 04/11/2010 postalCode: ‘10014’ state: ‘Alicante’ contact: scores: postalCode: ‘03204’ for_course: place: ‘Main building’ name: ‘Biology’ address: ‘123 Main St.’ address: ‘Calle 2’ grade: 4.0 city: ‘New York’ city: ‘Madrid’ postalCode: ‘10014’ for_course: state: ‘Madrid’ phone1: ‘900123456’ name: ‘English’ postalCode: ‘28080’ phone2: ‘900789873’ grade: 3.0 Wednesday, November 2, 2011
  • 23. MongoDB: por dónde empiezo • Map/Reduce, la bestia negra de NoSQL: Wednesday, November 2, 2011
  • 24. Plugins MongoDB • MongoDB GORM v.1.0.0.M7 --> http://www.grails.org/plugin/mongodb • Grails MongoDB v.0.5.4 --> http://www.grails.org/plugin/gorm-mongodb • Alternative MongoDB GORM based on the Morphia library v.0.7.5 --> http://www.grails.org/plugin/mongodb-morphia • MongoDB Tools v.0.1.2 --> http://www.grails.org/plugin/mongodb-tools • Mongodb Multitenant v.0.2.2.6-BETA --> http://www.grails.org/plugin/mongodb- multitenant • Spring MongoDB Datastore support for ZK v.1.1-M1 --> http://grails.org/ plugin/zk-mongodb Wednesday, November 2, 2011
  • 25. Plugin MongoDB GORM • Grails fue concebido con espíritu relacional (GORM con Hibernate) • Pero, ¿y ahora que queremos usar MongoDB? GORM MongoDB hasOne Embed / Reference hasMany Embed / Reference belongsTo Embed / Reference embedded Embed CONSEJO: No dejes que Grails condicione tu diseño MongoDB (NoSQL) Wednesday, November 2, 2011
  • 26. Plugin MongoDB GORM • Diseccionando el plugin nos encontramos: • Integración con GORM (Spring Data - Document Stores) • Uso del driver oficial Java para MongoDB • Uso de la librería GMongo (API al estilo Groovy) • Mapeador de BSON a tipos Groovy/Java • Soporte de métodos dinámicos, criterios y consultas nominadas (pero no HQL, M:N, proyecciones en criterios, y más...) • TRANSACCIONALIDAD --> ¿Magia? Wednesday, November 2, 2011
  • 27. Plugin MongoDB GORM • Mapeo de clases del dominio a colecciones Mongo: Reference Embedded class Person { String firstName String lastName static hasMany = [pets:Pet] class Person { } String firstName o bien String lastName Address address List<Address> otherAddresses class Person { static embedded = ['address', 'otherAddresses'] String firstName } String lastName } class Pet { String name String breed Person person } Wednesday, November 2, 2011
  • 28. Plugin MongoDB GORM • Mapeo de clases del dominio a colecciones Mongo (cont.): Identidad WriteConcern import org.bson.types.ObjectId import com.mongodb.WriteConcern class Person { class Person { ObjectId id String name } static mapping = { writeConcern WriteConcern.FSYNC_SAFE Índices } } class Person { String name static mapping = { name index:true, indexAttributes: [unique:true, dropDups:true] } } Wednesday, November 2, 2011
  • 29. Plugin MongoDB GORM • Mapeo de clases del dominio a colecciones Mongo (cont.): Geospacial Atributos dinámicos class Hotel { class Plant { String name boolean goesInPatch List location String name static mapping = { } location geoIndex:true, indexAttributes:[min:-500, max:500] def p = new Plant(name:"Pineapple") } p['color'] = 'Yellow' p['hasLeaves'] = true } p.save() p = Plant.findByName("Pineapple") new Hotel(name:"Hilton", location: [lat: 40.739037, long: 73.992964]).save() println p['color'] def h = Hotel.findByLocationNear([50, 60]) println p['hasLeaves'] assert h.name == 'Hilton' def box = [[40.73083, -73.99756], [40.741404, -73.988135]] def h = Hotel.findByLocationWithinBox(box) def center = [50, 50] def radius = 10 def h = Hotel.findByLocationWithinCircle([center, radius]) Wednesday, November 2, 2011
  • 30. Plugin MongoDB GORM • Demo 1 - 1:1 / M:1 sin ‘hasOne’ ni ‘belongsTo’ Paso 1. Crear un maestro y un detalle Thu Oct 27 17:46:59 [initandlisten] connection accepted from 192.168.0.102:53298 #54 Thu Oct 27 17:47:00 [conn54] remove prueba1.maestro query: {} 20ms Thu Oct 27 17:47:00 [conn54] query: prueba1.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 17:47:00 [conn54] run command prueba1.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 17:47:00 [conn54] query prueba1.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 33ms Thu Oct 27 17:47:00 [conn54] remove prueba1.detalle query: {} 0ms Thu Oct 27 17:47:00 [conn54] query: prueba1.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 17:47:00 [conn54] run command prueba1.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 17:47:00 [conn54] query prueba1.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 100ms Thu Oct 27 17:47:00 [conn54] insert prueba1.maestro 0ms Thu Oct 27 17:47:00 [conn54] insert prueba1.detalle 0ms > db.maestro.find() { "_id" : ObjectId("4ea97cf4a0ee87eee9573adf"), "nombre" : "Maestro1", "version" : 0 } > db.detalle.find() { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" : "Detalle1", "version" : 0 } Wednesday, November 2, 2011
  • 31. Plugin MongoDB GORM • Demo 1 - 1:1 / M:1 sin ‘hasOne’ ni ‘belongsTo’ Paso 2. Buscar un maestro e imprimir su detalle Thu Oct 27 17:50:47 [initandlisten] connection accepted from 192.168.0.102:53403 #55 Thu Oct 27 17:50:47 [conn55] query: prueba1.maestro{ nombre: "Maestro1" } Thu Oct 27 17:50:47 [conn55] used cursor: 0x100f5c520 Thu Oct 27 17:50:47 [conn55] query prueba1.maestro ntoreturn:1 reslen:92 nreturned:1 0ms Thu Oct 27 17:50:47 [conn55] query: prueba1.detalle{ maestro.$id: ObjectId('4ea97cf4a0ee87eee9573adf') } Thu Oct 27 17:50:47 [conn55] used cursor: 0x100f53d80 Thu Oct 27 17:50:47 [conn55] query prueba1.detalle ntoreturn:1 reslen:141 nreturned:1 0ms Wednesday, November 2, 2011
  • 32. Plugin MongoDB GORM • Demo 2 - 1:1 con ‘hasOne’ Paso 1. Crear un maestro y un detalle Thu Oct 27 18:14:10 [initandlisten] connection accepted from 192.168.0.102:53795 #63 Thu Oct 27 18:14:10 [conn63] remove prueba2.maestro query: {} 0ms Thu Oct 27 18:14:10 [conn63] query: prueba2.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 18:14:10 [conn63] run command prueba2.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 18:14:10 [conn63] query prueba2.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 0ms Thu Oct 27 18:14:10 [conn63] remove prueba2.detalle query: {} 0ms Thu Oct 27 18:14:10 [conn63] query: prueba2.$cmd{ getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 18:14:10 [conn63] run command prueba2.$cmd { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } Thu Oct 27 18:14:10 [conn63] query prueba2.$cmd ntoreturn:1 command: { getlasterror: 1, w: 1, wtimeout: 0, fsync: true } reslen:106 95ms Thu Oct 27 18:14:10 [conn63] insert prueba2.detalle 0ms Thu Oct 27 18:14:10 [conn63] insert prueba2.maestro 0ms > db.maestro.find() { "_id" : ObjectId("4ea98595a0ee4f17bac48f87"), "nombre" : "Maestro2", "version" : 0 } > db.detalle.find() { "_id" : ObjectId("4ea98595a0ee4f17bac48f88"), "nombre" : "Detalle2", "detalle" : { "$ref" : "maestro", "$id" : ObjectId("4ea98595a0ee4f17bac48f87") }, "version" : 0 } Wednesday, November 2, 2011
  • 33. Plugin MongoDB GORM • Demo 3 - 1:M con ‘hasMany’ Paso 1. Crear un maestro y varios detalled Thu Oct 27 18:37:23 [conn78] insert prueba3.detalle 0ms Thu Oct 27 18:37:23 [conn78] insert prueba3.maestro 0ms Thu Oct 27 18:37:23 [conn78] update prueba3.maestro query: { _id: ObjectId('4ea988c3a0ee8ac0c9c3cab7') } update: { _id: ObjectId('4ea988c3a0ee8ac0c9c3cab7'), nombre: "Maestro3", version: 0, detalles: [ { $ref: "maestro", $id: ObjectId('4ea988c3a0ee8ac0c9c3cab8') }, { $ref: "maestro", $id: ObjectId('4ea988c3a0ee8ac0c9c3cab9') }, { $ref: "maestro", $id: ObjectId('4ea988c3a0ee8ac0c9c3caba') } ] } byid 0ms > db.maestro.find() { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3cab7"), "nombre" : "Maestro3", "version" : 0, "detalles" : [ { "$ref" : "maestro", “$id" : ObjectId("4ea988c3a0ee8ac0c9c3cab8") }, { "$ref" : "maestro", “$id" : ObjectId("4ea988c3a0ee8ac0c9c3cab9") }, { "$ref" : "maestro", "$id" : ObjectId("4ea988c3a0ee8ac0c9c3caba") } ]} > db.detalle.find() { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3cab8"), "nombre" : "Detalle3.2", "version" : 0 } { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3cab9"), "nombre" : "Detalle3.1", "version" : 0 } { "_id" : ObjectId("4ea988c3a0ee8ac0c9c3caba"), "nombre" : "Detalle3.3", "version" : 0 } Wednesday, November 2, 2011
  • 34. Plugin MongoDB GORM • Demo 3 - 1:M con ‘hasMany’ Paso 2. Buscar un maestro e imprimir sus detalles Thu Oct 27 18:40:40 [conn78] query: prueba3.maestro{ nombre: "Maestro3" } Thu Oct 27 18:40:40 [conn78] used cursor: 0x101d33da0 Thu Oct 27 18:40:40 [conn78] query prueba3.maestro ntoreturn:1 reslen:236 nreturned:1 0ms Thu Oct 27 18:40:40 [conn78] query: prueba3.detalle{ _id: { $in: [ ObjectId('4ea988c3a0ee8ac0c9c3cab8'), ObjectId('4ea988c3a0ee8ac0c9c3cab9'), ObjectId('4ea988c3a0ee8ac0c9c3caba') ] } } Thu Oct 27 18:40:40 [conn78] used cursor: 0x101d34140 Thu Oct 27 18:40:40 [conn78] query prueba3.detalle reslen:210 nreturned:3 0ms Wednesday, November 2, 2011
  • 35. Plugin MongoDB GORM • Demo 4 - 1:M con detalles embebidos Paso 1. Crear un maestro y varios detalles Thu Oct 27 19:11:06 [conn94] insert prueba4.maestro 0ms > db.maestro.find() { "_id" : ObjectId("4ea990aaa0ee155609d17314"), "detalles" : [ { "nombre" : "Detalle4.1", "_embeddedClassName" : "prueba4.Detalle" }, { "nombre" : "Detalle4.2", "_embeddedClassName" : "prueba4.Detalle" }, { "nombre" : "Detalle4.3", "_embeddedClassName" : "prueba4.Detalle" } ], "nombre" : "Maestro4", "version" : 0 } > db.detalle.find() (No hay resultados porque ‘detalle’ no tiene entidad propia, sino que es un documento embebido en ‘maestro’) Wednesday, November 2, 2011
  • 36. Plugin MongoDB GORM • Demo 4 - 1:M con detalles embebidos Paso 2. Buscar un maestro e imprimir sus detalles Thu Oct 27 19:12:09 [conn95] query: prueba4.maestro{ nombre: "Maestro4" } Thu Oct 27 19:12:09 [conn95] used cursor: 0x100f4a9e0 Thu Oct 27 19:12:09 [conn95] query prueba4.maestro ntoreturn:1 reslen:320 nreturned:1 0ms Wednesday, November 2, 2011
  • 37. Plugin MongoDB GORM • De nuevo la pregunta del millón, ¿embedded o reference? • Depende del dominio de tu aplicación • Para 1:M opta en realidad por un M:1 <1>.get<M>() { <M>.findAllBy<1>(this) } • Usa embedded cuando la entidad ‘embebida’ carece de identidad propia fuera de su ‘contenedor’ • Pero si usas embedded, Grails tiene sus limitaciones :-( • Trees --> http://www.mongodb.org/display/DOCS/Trees+in +MongoDB Wednesday, November 2, 2011
  • 38. Plugin MongoDB GORM • Limitación 1 - Indexación de propiedades embebidas Wednesday, November 2, 2011
  • 39. Plugin MongoDB GORM • Limitación 1 - Indexación de propiedades embebidas Wednesday, November 2, 2011
  • 40. Plugin MongoDB GORM • Limitación 1 - Indexación de propiedades embebidas > db.system.indexes.find() { "name" : "_id_", "ns" : "detalle", "key" : { "_id" : 1 }, "v" : 0 } { "name" : "nombre_1", "ns" : "detalle", "key" : { "nombre" : 1 }, "v" : 0 } { "name" : "_id_", "ns" : "maestro", "key" : { "_id" : 1 }, "v" : 0 } { "name" : "nombre_1", "ns" : "maestro", "key" : { "nombre" : 1 }, "v" : 0 } { "name" : "detalles.nombre_1", "ns" : "maestro", "key" : { "detalles.nombre" : 1 }, "v" : 0 } Wednesday, November 2, 2011
  • 41. Plugin MongoDB GORM • Limitación 1 - Indexación de propiedades embebidas (cont.) Wednesday, November 2, 2011
  • 42. Plugin MongoDB GORM • Limitación 1 - Indexación de propiedades embebidas (cont.) > db.maestro.find({"detalles.nombre": "Detalle4.2"}) { "_id" : ObjectId("4ea990dfa0ee155609d17315"), "detalles" : [ { "nombre" : "Detalle4.1", "_embeddedClassName" : "Detalle" }, { "nombre" : "Detalle4.2", "_embeddedClassName" : "Detalle" }, { "nombre" : "Detalle4.3", "_embeddedClassName" : "Detalle" } ], "nombre" : "Maestro4", "version" : 0 } Wednesday, November 2, 2011
  • 43. Plugin MongoDB GORM • Limitación 1 - Indexación de propiedades embebidas (cont.) > db.maestro.find({"detalles.nombre": "Detalle4.2"}) > db.maestro.find({"detalles.nombre": "Detalle4.2"}).explain() { "_id" : ObjectId("4ea990dfa0ee155609d17315"), { "detalles" : [ "cursor" : "BtreeCursor detalles.nombre_1", { "nscanned" : 1, "nombre" : "Detalle4.1", "nscannedObjects" : 1, "_embeddedClassName" : "Detalle" "n" : 1, }, "millis" : 24, { "nYields" : 0, "nombre" : "Detalle4.2", "nChunkSkips" : 0, "_embeddedClassName" : "Detalle" "isMultiKey" : true, }, "indexOnly" : false, { "indexBounds" : { "nombre" : "Detalle4.3", "detalles.nombre" : [ "_embeddedClassName" : "Detalle" [ } "Detalle4.2", “Detalle4.2" ], "nombre" : "Maestro4", "version" : 0 } ] ] } } Wednesday, November 2, 2011
  • 44. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (DBRef) Wednesday, November 2, 2011
  • 45. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (DBRef) > db.system.indexes.find() { "name" : "_id_", "ns" : "detalle", "key" : { "_id" : 1 }, "v" : 0 } { "name" : "nombre_1", "ns" : "detalle", "key" : { "nombre" : 1 }, "v" : 0 } { "name" : "_id_", "ns" : "maestro", "key" : { "_id" : 1 }, "v" : 0 } { "name" : "nombre_1", "ns" : "maestro", "key" : { "nombre" : 1 }, "v" : 0 } { "name" : "maestro_1", "ns" : "detalle", "key" : { "maestro" : 1 }, "v" : 0 } Wednesday, November 2, 2011
  • 46. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) Wednesday, November 2, 2011
  • 47. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) Wed Nov 2 12:58:44 [conn1] query: detalle{ maestro.$id: ObjectId('4ea97cf4a0ee87eee9573adf') } Wed Nov 2 12:58:44 [conn1] used cursor: 0x101e02ac0 Wed Nov 2 12:58:44 [conn1] query detalle reslen:141 nreturned:1 0ms Wednesday, November 2, 2011
  • 48. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}) { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" : "Detalle1", "version" : 0 } Wednesday, November 2, 2011
  • 49. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}) { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" : "Detalle1", "version" : 0 } > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}).explain() { "cursor" : "BasicCursor", "nscanned" : 1, "nscannedObjects" : 1, "n" : 1, "millis" : 0, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : {} } Wednesday, November 2, 2011
  • 50. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) > db.detalle.find({'maestro': new DBRef('detalle', ObjectId("4ea97cf4a0ee87eee9573adf"))}) { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" : "Detalle1", "version" : 0 } Wednesday, November 2, 2011
  • 51. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) > db.detalle.find({'maestro': new DBRef('detalle', ObjectId("4ea97cf4a0ee87eee9573adf"))}) { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" : "Detalle1", "version" : 0 } > db.detalle.find({'maestro': new DBRef('detalle', ObjectId("4ea97cf4a0ee87eee9573adf"))}).explain() { "cursor" : "BtreeCursor maestro_1", "nscanned" : 1, "nscannedObjects" : 1, "n" : 1, "millis" : 0, "indexBounds" : { "maestro" : [ [ { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") } ]]}} Wednesday, November 2, 2011
  • 52. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (DBRef) Wednesday, November 2, 2011
  • 53. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (DBRef) Wednesday, November 2, 2011
  • 54. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (DBRef) > db.system.indexes.find() { "name" : "_id_", "ns" : "detalle", "key" : { "_id" : 1 }, "v" : 0 } { "name" : "nombre_1", "ns" : "detalle", "key" : { "nombre" : 1 }, "v" : 0 } { "name" : "_id_", "ns" : "maestro", "key" : { "_id" : 1 }, "v" : 0 } { "name" : "nombre_1", "ns" : "maestro", "key" : { "nombre" : 1 }, "v" : 0 } { "name" : "maestro.$id_1", "ns" : "detalle", "key" : { "maestro.$id" : 1 }, "v" : 0 } Wednesday, November 2, 2011
  • 55. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}) { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" : "Detalle1", "version" : 0 } Wednesday, November 2, 2011
  • 56. Plugin MongoDB GORM • Limitación 2 - Indexación de referencias (cont.) > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}) { "_id" : ObjectId("4ea97cf4a0ee87eee9573ae0"), "maestro" : { "$ref" : "detalle", "$id" : ObjectId("4ea97cf4a0ee87eee9573adf") }, "nombre" : "Detalle1", "version" : 0 } > db.detalle.find({"maestro.$id": "4ea97cf4a0ee87eee9573adf"}).explain() { "cursor" : "BtreeCursor maestro.$id_1", "nscanned" : 1, "nscannedObjects" : 1, "n" : 1, "millis" : 0, "indexBounds" : { "maestro.$id" : [ [ ObjectId("4ea97cf4a0ee87eee9573adf"), ObjectId("4ea97cf4a0ee87eee9573adf") ] ] } } Wednesday, November 2, 2011
  • 57. Plugin MongoDB GORM • Limitación 3 - Búsquedas sobre propiedades embebidas Wednesday, November 2, 2011
  • 58. Plugin MongoDB GORM • Limitación 3 - Búsquedas sobre propiedades embebidas Thu Oct 27 20:51:23 [conn99] query: maestro{ detalles.nombre: "Detalle4.2" } Thu Oct 27 20:51:23 [conn99] used cursor: 0x101d108d0 Thu Oct 27 20:51:23 [conn99] query maestro reslen:320 nreturned:1 0ms Wednesday, November 2, 2011
  • 59. Plugin MongoDB GORM • Limitación 3 - Búsquedas sobre propiedades embebidas Thu Oct 27 20:51:23 [conn99] query: maestro{ detalles.nombre: "Detalle4.2" } Thu Oct 27 20:51:23 [conn99] used cursor: 0x101d108d0 Thu Oct 27 20:51:23 [conn99] query maestro reslen:320 nreturned:1 0ms Pero luego, hay que obtener el detalle en cuestión... Wednesday, November 2, 2011
  • 60. Plugin MongoDB GORM • Limitación 3 - Búsquedas sobre propiedades embebidas Thu Oct 27 20:51:23 [conn99] query: maestro{ detalles.nombre: "Detalle4.2" } Thu Oct 27 20:51:23 [conn99] used cursor: 0x101d108d0 Thu Oct 27 20:51:23 [conn99] query maestro reslen:320 nreturned:1 0ms Pero luego, hay que obtener el detalle en cuestión... Wednesday, November 2, 2011
  • 61. Plugin MongoDB GORM • Limitación 4 - Búsquedas embebidas con múltiples coincidencias Wednesday, November 2, 2011
  • 62. Plugin MongoDB GORM • Limitación 4 - Búsquedas embebidas con múltiples coincidencias Thu Oct 27 20:53:45 [conn99] query: factura{ articulos.descripcion: "~/(i)iPhone/" } Thu Oct 27 20:53:45 [conn99] used cursor: 0x101f108e1 Thu Oct 27 20:53:45 [conn99] query factura reslen:932 nreturned:1 0ms Wednesday, November 2, 2011
  • 63. Plugin MongoDB GORM • Limitación 4 - Búsquedas embebidas con múltiples coincidencias Thu Oct 27 20:53:45 [conn99] query: factura{ articulos.descripcion: "~/(i)iPhone/" } Thu Oct 27 20:53:45 [conn99] used cursor: 0x101f108e1 Thu Oct 27 20:53:45 [conn99] query factura reslen:932 nreturned:1 0ms Pero como puede haber varias líneas que coincida la descripción de artículo... Wednesday, November 2, 2011
  • 64. Plugin MongoDB GORM • Limitación 4 - Búsquedas embebidas con múltiples coincidencias Thu Oct 27 20:53:45 [conn99] query: factura{ articulos.descripcion: "~/(i)iPhone/" } Thu Oct 27 20:53:45 [conn99] used cursor: 0x101f108e1 Thu Oct 27 20:53:45 [conn99] query factura reslen:932 nreturned:1 0ms Pero como puede haber varias líneas que coincida la descripción de artículo... Wednesday, November 2, 2011
  • 65. Plugin MongoDB GORM • Limitación 5 - Búsquedas por existencia en campos embebidos (e.j. facturas sin cobros) Wednesday, November 2, 2011
  • 66. Plugin MongoDB GORM • Limitación 5 - Búsquedas por existencia en campos embebidos (e.j. facturas sin cobros) Thu Oct 27 20:55:45 [conn99] query: factura{ cobros: { $exists: false } } Thu Oct 27 20:55:45 [conn99] used cursor: 0x2314508a1 Thu Oct 27 20:55:45 [conn99] query factura reslen:320 nreturned:15 0ms Wednesday, November 2, 2011
  • 67. Plugin MongoDB GORM • Limitación 6 - Búsquedas con $where (expresiones Javascript) Wednesday, November 2, 2011
  • 68. Plugin MongoDB GORM • Limitación 6 - Búsquedas con $where (expresiones Javascript) Thu Oct 27 21:55:45 [conn99] query: factura{ $where: “this.total > 1000” } Thu Oct 27 21:55:45 [conn99] used cursor: 0x101d42e20 Thu Oct 27 21:55:45 [conn99] query factura reslen:92 nreturned:13 0ms Wednesday, November 2, 2011
  • 69. Plugin MongoDB GORM • Limitación 7 - Búsquedas ‘low API’ en referencias (sin plugin) Wednesday, November 2, 2011
  • 70. Plugin MongoDB GORM • Limitación 7 - Búsquedas ‘low API’ en referencias (sin plugin) Thu Oct 27 21:56:23 [conn99] query: detalle{ maestro: { $ref: “detalle”, $id: ObjectId('4ea97cf4a0ee87eee9573adf') } } Thu Oct 27 21:56:23 [conn99] used cursor: 0x10302cba0 Thu Oct 27 21:56:23 [conn99] query factura reslen:141 nreturned:1 0ms Wednesday, November 2, 2011
  • 71. Plugin MongoDB GORM • Limitación 8.1 - Cálculos mediante Map/Reduce (servidor) Wednesday, November 2, 2011
  • 72. Plugin MongoDB GORM • Limitación 8.1 - Cálculos mediante Map/Reduce (servidor) Wednesday, November 2, 2011
  • 73. Plugin MongoDB GORM • Limitación 8.2 - Cálculos mediante agrupación (db.group) Wednesday, November 2, 2011
  • 74. Plugin MongoDB GORM • Limitación 8.2 - Cálculos mediante agrupación (db.group) [[odd:true, count:99.0], [even:true, count:56.0]] Wednesday, November 2, 2011
  • 75. Plugin MongoDB GORM • Limitación 8.3 - Procedimientos almacenados (db.eval) function my_erase() { db.things.find().forEach( function(obj) { delete obj.foo; db.things.save(obj); } ); } my_erase(); Wednesday, November 2, 2011
  • 76. Plugin MongoDB GORM • Limitación 8.3 - Procedimientos almacenados (db.eval) function my_erase() { db.things.find().forEach( function(obj) { delete obj.foo; db.things.save(obj); } ); } my_erase(); Para evitar cargar en cliente el contenido entero de la colección... Wednesday, November 2, 2011
  • 77. Plugin MongoDB GORM • Limitación 8.3 - Procedimientos almacenados (db.eval) function my_erase() { db.things.find().forEach( function(obj) { delete obj.foo; db.things.save(obj); } ); } my_erase(); Para evitar cargar en cliente el contenido entero de la colección... db.eval(my_erase); Wednesday, November 2, 2011
  • 78. Conclusiones • Lecciones aprendidas en mi experiencia de desarrollo: • Piensa muy bien el diseño de tu repositorio MongoDB • Si embebes colecciones, prevé si necesitarás identificar los elementos • Aprende GMongo: se convertirá en tu mejor aliado • No te dejes influenciar por lo que ofrece o no ofrece el plugin • MongoDB no es sólo CRUD: investiga, aprende, disfruta Wednesday, November 2, 2011
  • 79. Preguntas & Respuestas Wednesday, November 2, 2011

Hinweis der Redaktion

  1. \n
  2. \n\n\n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. 11 year old in Libya. Vest, waved. \nStand\nState that you&amp;#x2019;ll be leading the session and then do it\nTell people what to do\nIf you don&amp;#x2019;t:\nsomeone else will\nno one will\n\n
  10. Quakers\nAsk for buy in on the objective \nAsk for buy in on participation\nChange the agenda if the group wants to \nIf you don&amp;#x2019;t: \nwhen people don&amp;#x2019;t share ownership, they don&amp;#x2019;t care\n\n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n\n
  22. \n
  23. &amp;#x201C;Bob, I&amp;#x2019;d love to hear from the entire team while we have everyone here today. Could you let everyone know if that&amp;#x2019;s something you support?&amp;#x201D; \n\n\n\n
  24. \n
  25. \n\n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n\n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n