Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to execute native mongo methods in meteor app environment?

Tags:

mongodb

meteor

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?

like image 875
Alexander Skiller Avatar asked Oct 19 '22 07:10

Alexander Skiller


1 Answers

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
like image 92
Billybobbonnet Avatar answered Nov 01 '22 09:11

Billybobbonnet