javascript - Get sums by grouping a collection in Meteor -
i have collection fields: number
, a
, b
, c
.
i want divide collection in 3 based on number , separate sums of a
, b
, , c
each group division.
i have done with
function sumlist(amountlist) { return _.reduce(amountlist, function(sum, amount) { return sum + amount; }, -1); } // cursors var group1 = groups.find({ number: { $lte: 32 } }).fetch(); var group2 = groups.find({ number: { $gte: 33, $lte: 70 } }).fetch(); var group3 = groups.find({ number: { $gte: 71 } }).fetch(); // sums group1 var group1suma = sumlist(_.pluck(group1, "a")); var group1sumb = sumlist(_.pluck(group1, "b")); var group1sumc = sumlist(_.pluck(group1, "c")); // sums group2 var group2suma = sumlist(_.pluck(group2, "a")); var group2sumb = sumlist(_.pluck(group2, "b")); var group2sumc = sumlist(_.pluck(group2, "c")); // sums group3 var group3suma = sumlist(_.pluck(group3 "a")); var group3sumb = sumlist(_.pluck(group3, "b")); var group3sumc = sumlist(_.pluck(group3, "c"));
it works think code ugly.
i wonder if can done smart mapping. besides, guess might have bad performance.
how can these sums optimized?
use aggregation framework have $match
pipeline operator filter collection on number
field. $group
pipeline step groups filtered input documents , applies accumulator expression $sum
each field sums.
your pipeline this:
var pipeline = [ { "$match": { "number": { "$lte": 32 } } /* group1 filter */ }, { "$group": { "_id": 0, "suma": { "$sum": "$a" }, "sumb": { "$sum": "$b" }, "sumc": { "$sum": "$c" } } } ];
you can add meteorhacks:aggregate package implement aggregation in meteor:
add app with
meteor add meteorhacks:aggregate
since package exposes .aggregate
method on mongo.collection instances, can call method resulting array document has sums. example
if (meteor.isserver) { var coll = new mongo.collection('collectionname'); meteor.methods({ sumlist: function (filter) { var pipeline = [ { "$match": filter }, { "$group": { "_id": 0, "suma": { "$sum": "$a" }, "sumb": { "$sum": "$b" }, "sumc": { "$sum": "$c" } } } ]; var result = coll.aggregate(pipeline); return result[0]; } }); } if (meteor.isclient) { // filters var group1 = { "number": { "$lte": 32 } }; var group2 = { "number": { "$gte": 33, "$lte": 70 } }; var group3 = { "number": { "$gte": 71 } }; meteor.call('sumlist', group1, callback); //meteor.call('sumlist', group2, callback); //meteor.call('sumlist', group3, callback); function callback(err, result) { console.log(result) } }
Comments
Post a Comment