En mongodb tengo 2 colecciones como esta
var collection1Schema = new Schema({ moneyPaid:{ type:Number } }, {collection: 'collection1'}); var collection2 = new Schema({ coll_id: { type: Schema.ObjectId, ref: 'collection1' }, isBook: { type: Boolean, } }, {collection: 'collection2'});
Quiero la sum de todo el moneypaid
desde collection1
que tiene el valor verdadero de isBook
en collection2
.
Dependiendo de las necesidades de su sistema, creo que el diseño del modelo podría simplificarse creando solo una colección que combine todos los atributos de collection1
y collection2
. Como ejemplo:
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var accountSchema = new Schema({ moneyPaid:{ type: Number }, isBook: { type: Boolean, } }, {collection: 'account'}); var Account = mongoose.model('Account', accountSchema);
en el que luego puede ejecutar la canalización de agregación
var pipeline = [ { "$match": { "isBook" : true } }, { "$group": { "_id": null, "total": { "$sum": "$moneyPaid"} } } ]; Account.aggregate(pipeline, function(err, results) { if (err) throw err; console.log(JSON.stringify(results, undefined, 4)); });
Sin embargo, con el diseño de esquema actual, primero tendría que obtener los identificadores para collection1, que tienen un valor real de BookBook en collection2
y luego usar esa lista de id como la consulta $match
en la agregación del modelo collection1
, algo como lo siguiente:
collection2Model.find({"isBook": true}).lean().exec(function (err, objs){ var ids = objs.map(function (o) { return o.coll_id; }), pipeline = [ { "$match": { "_id" : { "$in": ids } } }, { "$group": { "_id": null, "total": { "$sum": "$moneyPaid"} } } ]; collection1Model.aggregate(pipeline, function(err, results) { if (err) throw err; console.log(JSON.stringify(results, undefined, 4)); }); });