Mongoose 聚合游标承诺

sav*_*ver 2 javascript mongoose node.js

我正在尝试聚合一个大型数据集,因此我将游标与聚合一起使用。但是,我无法找到有关如何在不使用额外延迟的情况下实现这一点的文档。我觉得必须有一种方法可以aggregate().cursor().each()与聚合完成后解决的承诺相结合。有谁知道如何做到这一点?

此代码有效并且基于http://mongoosejs.com/docs/api.html#aggregate_Aggregate-cursor 我试图找到一种无需额外承诺的方法。

aggregation = MyModel.aggregate().group({
  _id: '$name'
});

deferred = Q.defer();

aggregation.cursor({
  batchSize: 1000
}).exec().each(function(err, doc) {
  if (err) {
    return deferred.reject(err);
  }
  if (!doc) {
    return deferred.resolve(); // done
  }
  // do stuff with doc
});
return deferred.promise;
Run Code Online (Sandbox Code Playgroud)

Dyl*_*ght 5

我发现this SO正在寻找有关使用带有承诺的聚合游标的一般帮助。经过大量的反复试验,如果其他人偶然发现了这一点,我发现游标对象有一个 next() 方法,它像其他游标一样返回一个承诺。但是,出于某种原因,如果没有async标志,我就无法获得对它的引用。因此,如果您使用蓝鸟:

let bluebird = require("bluebird");
let aggregation = MyModel.aggregate().group({
  _id: '$name'
});

aggregation.cursor({
  batchSize: 1000,
  async: true
}).exec().then(cursor => {
  return bluebird.coroutine(function* () {
    let doc;
    while ((doc = yield cursor.next())) {
      console.log(doc._id)
    }
  })()
}).then(() => { console.log("done with cursor"); })
Run Code Online (Sandbox Code Playgroud)

猫鼬 5 的更新

exec()呼叫不再返回一个承诺,只要将光标本身,async: true物业不再是必要的。

let aggregation = MyModel.aggregate().group({
  _id: '$name'
});

(async function () {
  let doc, cursor;
  cursor = aggregation.cursor({batchSize: 1000}).exec();

  while ((doc = await cursor.next())) {
    console.log(doc._id)
  }
})()
.then(() => console.log("done with cursor"); )
Run Code Online (Sandbox Code Playgroud)