¿Cómo realizar consultas entre uniones en Mongoose?
Populate en mongoose
Si bien no existen relaciones en las bases de datos NoSQL, podemos llevar acabo este proceso relacional a nivel del código de la aplicación. Mongoose provee una característica llamada population. Esta permite llenar ciertas partes del documento desde otra colección. Supongamos que tenemos las colecciones publicaciones y autores. Podemos agregar una referencia a las publicaciones desde el esquema de autores.
Populate en mongoose ejemplo
const mongoose = require("mongoose");
const autorSchema = mongoose.Schema({
_id: Number,
nombre: String,
publicaciones: [
{
type: Schema.Types.ObjectId,
ref: "Publicaciones",
},
],
});
const publicacionSchema = mongoose.Schema({
_autor: { type: Number, ref: "Autor" },
titulo: String,
});
const Publicacion = mongoose.model("Publicacion", publicacionSchema);
const Autor = mongoose.model("Autor", autorSchema);
Autor.findOne({ name: "Gabriel Garcia Marquez" })
.populate("publicaciones")
.exec((err, autor) => {
if (err) {
console.log(err);
process.exit(-1);
}
console.log(
`Tl autor ${autor.nombre} tiene ${autor.publicaciones.length} publicaciones`
);
});
Los tipos de datos ObjectId, Number, String y Buffer son tipos validos para ser usados como referencias.
También es posible regresar solo una porción de los datos asociados ordenados por un campo en específico.
.populate({
path: 'publicaciones',
options: { limit: 10, sort: { titulo: 1 } }
})
Si se desea obtener solo ciertos campos de las colecciones asociadas.
.populate({
path: 'publicaciones',
select: '_id titulo', // separados por un espacio
options: { limit: 10, sort: { titulo: 1 } }
})
Incluso se puede aplicar un filtro a los resultados.
.populate({
path: 'publicaciones',
select: '_id titulo',
match: { titulo: /cien/i },
options: { limit: 10, sort: { titulo: 1 } }
})
La mejor forma de realizar esta operación es utilizando
select
y eligiendo solo los campos requeridos. De esta forma se previene sobrecargar una consulta y retraer datos sensitivos dentro de esta.