mongoose 5.0.3 "Aggregate has empty pipeline"

Created on 7 Feb 2018  路  4Comments  路  Source: Automattic/mongoose

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
Aggregate query not working, was working in 4.11 with same data.

mongo version 3.6

error:

0|startAPI |   Error:  Aggregate has empty pipeline
0|startAPI |
0|startAPI |   - aggregate.js:692 utils.promiseOrCallback.cb
0|startAPI |     [3.8.0]/[mongoose]/lib/aggregate.js:692:17
0|startAPI |
0|startAPI |   - utils.js:222 Promise
0|startAPI |     [3.8.0]/[mongoose]/lib/utils.js:222:5
0|startAPI |
0|startAPI |   - new Promise
0|startAPI |
0|startAPI |   - utils.js:221 Object.promiseOrCallback
0|startAPI |     [3.8.0]/[mongoose]/lib/utils.js:221:10
0|startAPI |
0|startAPI |   - aggregate.js:690 Aggregate.exec
0|startAPI |     [3.8.0]/[mongoose]/lib/aggregate.js:690:16
0|startAPI |
0|startAPI |   - stats.js:30 router.get
0|startAPI |     <omitted>
0|startAPI |
0|startAPI |
0|startAPI |   - next_tick.js:228 process._tickDomainCallback
0|startAPI |     internal/process/next_tick.js:228:7

0|startAPI | error: uncaughtException: callback.apply is not a function date=Wed Feb 07 2018 16:50:39 GMT+0000 (UTC), pid=25689, uid=1000, gid=1000, cwd=<omitted> execPath=/home/ubuntu/.nvm/versions/node/v9.0.0/bin/node, version=v9.0.0, argv=[/home/ubuntu/.nvm/versions/node/v9.0.0/bin/node, /usr/lib/node_modules/pm2/lib/ProcessContainerFork.js], rss=329207808, heapTotal=264351744, heapUsed=242126328, external=21623291, loadavg=[0.0380859375, 0.08154296875, 0.02734375], uptime=8038223, trace=[], stack=[  TypeError:  callback.apply is not a function ,   ,   - model.js:3928 ,     [3.8.0]/[mongoose]/lib/model.js:3928:16,   ,   - aggregate.js:693 utils.promiseOrCallback.cb,     [3.8.0]/[mongoose]/lib/aggregate.js:693:14,   ,   - utils.js:211 Object.promiseOrCallback,     [3.8.0]/[mongoose]/lib/utils.js:211:14,   ,   - aggregate.js:690 Aggregate.exec,     [3.8.0]/[mongoose]/lib/aggregate.js:690:16,   ,   - model.js:2809 Function.aggregate,     [3.8.0]/[mongoose]/lib/model.js:2809:13,   ,   - stats.js:28 router.get,     <omitted>,   ,   ,   - next_tick.js:228 process._tickDomainCallback,     internal/process/next_tick.js:228:7,   , ]

route and query:

router.get('/', async (req, res, next) => {
  try {
    var match = { status: 'active' };
    var group = {
      _id: null,
      patients: { $sum: '$patients' },
      matchedPatients: { $sum: '$matchedPatients' }
    };
    const matches = await Subscriptions.aggregate({ $match: match }, { $group: group })
      .allowDiskUse(true)
      .exec();
    var patients = matches && matches[0] ? matches[0].patients : 0;
    var matchedPatients = matches && matches[0] ? matches[0].matchedPatients : 0;
    var percentMatch = patients && matchedPatients ? Number(matchedPatients / patients * 100).toFixed(0) : 0;
    res.json({
      patients,
      matchedPatients,
      percentMatch
    });
  }
  catch (err) {
    next(10031);
  }
});

I was able to fix it by removing the .exec() and putting the pipeline objects into an array. Only reporting as an issue because it worked pre-upgrade. I'd be glad to help fix it or document the change if someone could point me in the right direction 馃榾

after the change my query looks like this:

const matches = await Subscriptions.aggregate([{ $match: match }, { $group: group }]).allowDiskUse(true);
enhancement

Most helpful comment

Yeah you need to do Subscriptions.aggregate([{ $match: match }, { $group: group }]) instead, mongoose 5 dropped support for passing a spread to aggregate(): https://github.com/Automattic/mongoose/blob/master/migrating_to_5.md#aggregate-parameters

All 4 comments

I suppose we could just wrap the value in an array if its an object

Yeah you need to do Subscriptions.aggregate([{ $match: match }, { $group: group }]) instead, mongoose 5 dropped support for passing a spread to aggregate(): https://github.com/Automattic/mongoose/blob/master/migrating_to_5.md#aggregate-parameters

I had a mistake like that and managed to rev up like this:
function(callback){
Club.aggregate([{ $group: { _id: "$country"}}
],(err, newResult) =>{
callback(err, newResult);
});
}

I had a mistake like that and managed to rev up like this:
function(callback){
Club.aggregate([{ $group: { _id: "$country"}}
],(err, newResult) =>{
callback(err, newResult);
});
}

Thanks!

Was this page helpful?
0 / 5 - 0 ratings