The Model
object provides an aggregate()
method that allows you to implement the MongoDB aggregation pipeline discussed in Chapter 15. If you haven’t already read the aggregation information in Chapter 15, you should read it before you read this section. It works here very similarly to the way it works in the MongoDB Node.js native driver. In fact, you can use exactly the same syntax if you want to. You also have the option of using the Mongoose Aggregate
object to build and then execute the aggregation pipeline.
The Aggregate
object works very similarly to the Query
object in that if you pass in a callback function, aggregate()
is executed immediately; if not, an Aggregate
object is returned, and you can apply pipeline methods.
For example, the following calls the aggregate()
method immediately:
model.aggregate([{$match:{value:15}}, {$group:{_id:"$name"}}],
function(err, results) {});
You can also pipeline aggregation operations by using an instance of the Aggregate
object. For example:
var aggregate = model.aggregate();
aggregate.match({value:15});
aggregate.group({_id:"$name"});
aggregate.exec();
Table 16.6 describes the methods that can be called on the Aggregate
object.
Listing 16.10 illustrates three examples of aggregation in Mongoose. The first example, in lines 9–19, implements aggregation in the native driver way but by using the Model
object. The aggregated result set is the largest and smallest word sizes for words that begin with a vowel.
The next example, in lines 20–27, implements aggregation by creating an Aggregate
object and appending operations to it by using the match()
, append()
, and limit()
methods. The results are stats for the five four-letter words.
The final example, in lines 28–35, uses the group()
, sort()
, and limit()
methods to build the aggregation pipeline that results in the top five letters with the largest average word size. Figure 16.10 shows the output of the code in Listing 16.10.
01 var mongoose = require('mongoose'),
02 var db = mongoose.connect('mongodb://localhost/words'),
03 var wordSchema = require('./word_schema.js').wordSchema;
04 var Words = mongoose.model('Words', wordSchema);
05 setTimeout(function(){
06 mongoose.disconnect();
07 }, 3000);
08 mongoose.connection.once('open', function(){
09 Words.aggregate([{$match: {first:{$in:['a','e','i','o','u']}}},
10 {$group: {_id:"$first",
11 largest:{$max:"$size"},
12 smallest:{$min:"$size"},
13 total:{$sum:1}}},
14 {$sort: {_id:1}}],
15 function(err, results){
16 console.log("
Largest and smallest word sizes for " +
17 "words beginning with a vowel: ");
18 console.log(results);
19 });
20 var aggregate = Words.aggregate();
21 aggregate.match({size:4});
22 aggregate.limit(5);
23 aggregate.append({$project: {_id:"$word", stats:1}});
24 aggregate.exec(function(err, results){
25 console.log("
Stats for 5 four letter words: ");
26 console.log(results);
27 });
28 var aggregate = Words.aggregate();
29 aggregate.group({_id:"$first", average:{$avg:"$size"}});
30 aggregate.sort('-average'),
31 aggregate.limit(5);
32 aggregate.exec( function(err, results){
33 console.log("
Letters with largest average word size: ");
34 console.log(results);
35 });
36 });