Alexander Skiller
Alexander Skiller

Reputation: 303

how to execute native mongo methods in meteor app environment?

Meteor supports only few methods on mongo collections such as find, findOne, insert, update, upsert, remove, allow, deny My question is, how do I perform all the others? I want to use aggregate on server side, like this:

db.eshops.aggregate([
  {
    $unwind: '$unpairedCategories'
  }, {
    $group: {
      _id: '$_id',
      'sum': {
        $sum: 1
      }
    }
  }, {
    $group: {
      _id: null,
      total_sum: {
        '$sum': '$sum'
      }
    }
  }
]);

should I include mongodb driver for nodejs separately from meteor? Or what is the meteor way to run all the other mongo collection methods?

Upvotes: 5

Views: 542

Answers (1)

Billybobbonnet
Billybobbonnet

Reputation: 3226

One of the seven principles of Meteor is database everywhere, i.e. you should be able to perform all the allowed operations both on client and server side (assuming several differences, such as allow deny rules for client). I guess this is why you can't have all mongo methods: they are not feasible on minimongo, the client side version of your mongo collection.

However, if you are ready to give up the reactivity, you can create a pipe to handle the aggregate commands, by adding this to your server startup code (code taken from here):

wrapAsync = (Meteor.wrapAsync)? Meteor.wrapAsync : Meteor._wrapAsync;
Mongo.Collection.prototype.aggregate = function(pipelines) {
  var coll;
  if (this.rawCollection) {
    // >= Meteor 1.0.4
    coll = this.rawCollection();
  } else {
    // < Meteor 1.0.4
    coll = this._getCollection();
  }
  return wrapAsync(coll.aggregate.bind(coll))(pipelines);

You have two possible alternatives/workaround if you want to keep the reactivity.

  1. create extra fields using collection hooks. You basically include the computed fields in the collection. This is a scalable solution, and it does not requires to add an extra load to the server
  2. You use the cursor.Observe() feature and you make a mix of clever filtering and custom JS methods (e.g. sum) to achieve similar results to what you need from the aggregate method. Note that you keep the reactivity but each server (if you plan to scale on several) needs to Observe() the collections. Check this example: https://stackoverflow.com/a/30813050/3793161

Upvotes: 3

Related Questions