Referencias en mongoDB

MongoDB no soporta JOINs (ver este post para ver una solución) puesto que como base de datos documental en MongoDB los datos se almacenan en documentos denormalizados o con datos referencias y no son necesarios los JOINs.

Normalmente almacenaremos nuestras estructuras en un único documento aunque en algunas ocasiones tiene sentido almacenar información relacionada en documentos separados en diferentes colecciones.

En MongoDB se pueden usar 2 métodos para relacionar documentos:

· Manual References: en la que se guarda el campo _id de un documento como referencia en otro documento. En este modelo la aplicación debe ejecutar una segunda consulta para devolver los datos relacionados.

· DBRefs son referencias de un documento a otro utilizando el valor del campo del primer documento _id, nombre de la colección (y opcionalmente el nombre de base de datos). Con esto los DBRefs permiten vincular documentos de varias colecciones para linkarse en una sola colección. Los DBRefs proporcionan en esencia una semántica común para la representación de los vínculos entre documentos. Los DBRefs también requieren consultas adicionales para devolver los documentos de referencia. Por otro lado la mayoría de los drivers ofrecen métodos de utilidad para hacer la query de la DBRef de forma automática.

En general se usan las Manual References.

Ver más

Veamos un ejemplo de Manual References muy ilustrativo, si tengo:

Authors:

db.authors.insert([

{

_id: ‘a1’,

name: { first: ‘orlando’, last: ‘becerra’ },

age: 27

},

{

_id: ‘a2’,

name: { first: ‘mayra’, last: ‘sanchez’ },


age: 21

}

]);

Categories:

db.categories.insert([
    {
        _id: 'c1',
        name: 'sci-fi'
    },
    {
        _id: 'c2',
        name: 'romance'
    }
]);

Books:

db.books.insert([
    {
        _id: 'b1',
        name: 'Groovy Book',
        category: 'c1',
        authors: ['a1']
 },
 {
 _id: 'b2',
 name: 'Java Book',
 category: 'c2',
 authors: ['a1','a2']
},
]);

Book lending:

db.lendings.insert([
    {
        _id: 'l1',
        book: 'b1',
        date: new Date('01/01/11'),
        lendingBy: 'jose'
    },
    {
        _id: 'l2',
        book: 'b1',
        date: new Date('02/02/12'),
        lendingBy: 'maria'
    }
]);

Y ejecuto:

db.books.find().forEach(
 function (newBook) {
 newBook.category = db.categories.findOne( { "_id": newBook.category } );
 newBook.lendings = db.lendings.find( { "book": newBook._id } ).toArray();
 newBook.authors = db.authors.find( { "_id": { $in: newBook.authors } } ).toArray();
db.booksReloaded.insert(newBook);
 }
);

Puedo hacer una consulta de la nueva colección booksReloaded:

db.booksReloaded.find().pretty()

que me devolverá una colección con los libros, su categoría, autores,….

{
 "_id" : "b1",
"name" : "Groovy Book",
 "category" : {
 "_id" : "c1",
 "name" : "sci-fi"
 },
 "authors" : [
        {
            "_id" : "a1",
            "name" : {
                "first" : "orlando",
                "last" : "becerra"
            },
            "age" : 27
        }
    ],
 "lendings" : [
        {
            "_id" : "l1",
            "book" : "b1",
            "date" : ISODate("2011-01-01T00:00:00Z"),
            "lendingBy" : "jose"
        },
        {
            "_id" : "l2",
            "book" : "b1",
            "date" : ISODate("2012-02-02T00:00:00Z"),
            "lendingBy" : "maria"
        }
    ]
}
{
 "_id" : "b2",
 "name" : "Java Book",
 "category" : {
 "_id" : "c2",
 "name" : "romance"
 },
 "authors" : [
        {
            "_id" : "a1",
            "name" : {
                "first" : "orlando",
                "last" : "becerra"
            },
            "age" : 27
        },
        {
            "_id" : "a2",
            "name" : {
                "first" : "mayra",
                "last" : "sanchez"
            },
            "age" : 21
        }
    ],
 "lendings" : [ ]
}

Deja un comentario