Group by in node.js-mongodb

user3061943 picture user3061943 · Jan 18, 2015 · Viewed 7.5k times · Source

I want to use group by in my server.js, but i get this error:

TypeError:Object #(Collection) has no method 'group'

I looked online and saw thats the function's name.

Here is what i wrote:

var monk = require('monk');
var db = monk('localhost:27017/Messages');
var collection = db.get('col');
collection.group(['a'], {}, {}, {}, function (e, docs) {
  res.json(docs);
});

Can anyone tell me what's wrong? Thank you!

Answer

Neil Lunn picture Neil Lunn · Jan 19, 2015

Monk does not implement a .group() method on it's own, but there is a .col accessor available from which you can get the native Collection object from the underlying driver and use it's methods.

Your usage for .group() is a bit off, so I'll use my data an example:

{
    "_id" : ObjectId("5479c4793815a1f417f537a0"),
    "status" : "canceled",
    "date" : ISODate("2014-11-29T00:00:00.000Z"),
    "offset" : 30,
},
{
    "_id" : ObjectId("5479c4793815a1f417d557a0"),
    "status" : "done",
    "date" : ISODate("2014-10-20T00:00:00.000Z"),
    "offset" : 30,
},
{
    "_id" : ObjectId("5479c4793815a1f417f117a0"),
    "status" : "done",
    "date" : ISODate("2014-12-29T00:00:00.000Z"),
    "offset" : 30,
}

Then you can just code up a .group() statement like this:

  var db = require('monk')('localhost/test'),
      sample = db.get('sample');

  sample.col.group(
    ["status"],
    {},
    { "count": 0 },
    "function (obj,prev) { prev.count++; }",
    function(err,docs) {
      if (err) console.log(err);
      console.log( docs );
    }
  );

But that also goes to show that 99% of the time you probably really want the .aggregate() method instead:

  var db = require('monk')('localhost/test'),
      sample = db.get('sample');

  sample.col.aggregate(
      [
          { "$group": {
              "_id": "$sample",
              "count": { "$sum": 1 }
          }}
      ],
      function(err,docs) {
         if (err) console.log(err);
         console.log( docs );
      }
  );

The aggregation framework is generally a lot more flexible than .group() and runs native code operators as opposed to interpreted JavaScript, so it's pretty worthwhile learning.