Grouping Results

When performing operations on large data sets, it is often useful to group the results based on the distinct values of one or more fields in a document. You could do this in code after retrieving the documents, but it is much more efficient to have MongoDB do it for you as part of a single request that is already iterating though the documents.

To group the results of a query together, you can use the group() method on the Collection object. The group() request first collects all the documents that match a query and then adds a group object to an array, based on distinct values of a set of keys, performs operations on the group objects, and returns the array of group objects. The syntax for the group() methods is shown below:

group(keys, query, initial, reduce, finalize, command, [options], callback)

The parameters of the group() method are described in the following list:

Image keys: This can be an object, an array, or a function that expresses the keys to group by. The simplest method is to specify the key(s) in an object such as {field1:true, field2:true} or an array such as ['first', 'last'].

Image query: The query object defines which documents to include in the initial set. See Table 15.1 for a list of query object options.

Image initial: Specifies an initial group object to use when aggregating data while grouping. An initial group object is created for each distinct set of keys. The most common use is a counter that tracks the number of items that match the keys. For example:

{"count":0}

Image reduce: This function has two parameters, obj and prev. This function is executed on each document that matches the query. The obj parameter is the current document, and prev is the object that was created by the initial parameter. You can then use the obj object to update the prev object with new values such as counts or sums. For example, to increment the count value, you use:

function(obj, prev) { prev.count++; }

Image finalize: This function accepts one parameter, obj, which is the final object resulting from the initial parameter and is updated as prev in the reduce function. This function is called on the resulting object for each distinct key before returning the array in the response.

Image command: This is a Boolean that, when true, indicates that the command runs using the internal group command instead of eval(). The default is true.

Image options: This object allows you to define the readPreference option.

Image callback: This option accepts an error as the first parameter and an array of the results objects as the second.

Listing 15.8 shows how to implement grouping of words based on various key sets. Lines 10–18 implement a basic grouping of words by first and last letter. The query in line 11 limits the words to those that begin with o and end with a vowel. The initial object for each has a count property only, which is updated for each matching document in the function on line 13.

Lines 19–28 sum the total vowels in the documents and group them together by incrementing prev.totalVowels with the obj.stats.vowels value in line 23. Then lines 29–40 use a finalize function that adds a new obj.total property to the group object that is a sum of the obj.vowels and obj.consonants properties of the object. Figure 15.8 shows the output for the code in Listing 15.8.

Listing 15.8 doc_group.js: Grouping a set of documents by specific fields in a MongoDB collection


01 var MongoClient = require('mongodb').MongoClient;
02 MongoClient.connect("mongodb://localhost/", function(err, db) {
03   var myDB = db.db("words");
04   myDB.collection("word_stats", groupItems);
05   setTimeout(function(){
06     db.close();
07   }, 3000);
08 });
09 function groupItems(err, words){
10   words.group(['first','last'],
11               {first:'o',last:{$in:['a','e','i','o','u']}},
12               {"count":0},
13               function (obj, prev) { prev.count++; }, true,
14               function(err, results){
15         console.log(" 'O' words grouped by first and last" +
16                     " letter that end with a vowel: ");
17         console.log(results);
18   });
19   words.group(['first'],
20               {size:{$gt:13}},
21               {"count":0, "totalVowels":0},
22               function (obj, prev) {
23                 prev.count++; prev.totalVowels += obj.stats.vowels;
24               }, {}, true,
25               function(err, results){
26     console.log(" Words grouped by first letter larger than 13: ");
27     console.log(results);
28   });
29   words.group(['first'],{}, {"count":0, "vowels":0, "consonants":0},
30               function (obj, prev) {
31                 prev.count++;
32                 prev.vowels += obj.stats.vowels;
33                 prev.consonants += obj.stats.consonants;
34               },function(obj){
35                 obj.total = obj.vowels + obj.consonants;
36               }, true,
37               function(err, results){
38         console.log(" Words grouped by first letter with totals: ");
39         console.log(results);
40   });
41 }


Image

Figure 15.8 Grouping documents from a MongoDB collection by specific field values.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.131.152.166