Cursor in aggregation due to MongoDB 3.6 req?

I have a Meteor app with several aggregations that runs fine on local. I’m using Meteor 1.2.1, simply because upgrading breaks a lot of features that I don’t know how to fix and this app is just a prototype. MongoDB version is 2.6.7. I have the meteorhacks:aggregate package installed.

I deployed to Galaxy using an M0 instance of MongoDB Atlas, which uses MongoDB 4.0.

The issue is that, as of MongoDB 3.6, aggregation requires a cursor, which I wasn’t using before and can’t figure out how to add.

The code I have, which works locally, is:

var comps = Companies.aggregate(pipeline);
comps.forEach(function (results) {
    Valuations.update({_id: valuationId}, {$set: {multiples: results}});
});

I tried the following edit, but with this it no longer works on local and does not work in production.

var comps = Companies.aggregate(pipeline, {cursor: {batchSize: 0}});

What am I missing to use a cursor?

For non-reactive aggregation use sakulstra:aggregate.

For reactive aggregation use tunguska:reactive-aggregate.

1 Like

Thank you Rob. I replaced meteorhacks:aggregate with sakulstra:aggregate however, the aggregation still does not work.

This code works fine on local but not in production:

var pipelineComps = [//Multi-stage pipeline//]
var comps = Companies.aggregate(pipelineComps);

If I revise as below, it no longer works on local or in production.

var pipelineComps = [//Multi-stage pipeline//]
var comps = Companies.aggregate(pipelineComps, {cursor: {}});

I checked every possible break along the way and the only thing that breaks the process is adding {cursor: {}}. From the MongoDB docs, it looks like this is all that is needed in order to use a cursor. Is there something else that needs to be added?

Your basic issue is one of incompatible MongoDB and Meteor versions. The version of Mongo and its API you have locally uses the old way of returning aggregation results.

On Galaxy, with MongoDB 3.6 and its API, an aggregation cursor is returned.

I don’t think there’s an easy, “plug-compatible” way of resolving that discrepancy, especially given that you won’t get an Atlas version of Mongo old enough for Meteor 1.2.1.

Your options seem to be:

  • Install and host your own MongoDB 2.6.7 (sounds expensive and unsupported).
  • Take the hit and do a full update to the latest Meteor - do it in release steps to minimise the risk of too many changes at once.
  • Upgrade Meteor to a version whose MongoDB uses the new cursor form of aggregation. You’d need to research Meteor and MongoDB changelogs to see if you can find a combo you can upgrade to.
  • Maintain a “Galaxy only” version of your app, with some code changes to get an array from the cursor. See code below. You may get lucky - Meteor’s Promise package did exist in 1.2.1.
var cursor= Companies.aggregate(pipeline);
var comps = Promise.await(cursor.toArray());
comps.forEach(...

I use a similar technique here:

Rob, much appreciated. I was afraid the older Meteor version was the culprit. I’m going to try to slowly upgrade.

I also tried your suggested code above and it again works fine for me on local, but not in production on Galaxy. I may also go back to Digital Ocean - I had deployed previously there and it worked perfectly.

1 Like

Nice little surprise - I took a shot and updated Meteor to the most recent version and everything works fine in production and deployment! Little slow, but it works.

1 Like