【问题标题】:Mongoose Error: Arguments must be aggregate pipeline operatorsMongoose 错误:参数必须是聚合管道运算符
【发布时间】:2016-09-17 08:40:31
【问题描述】:

我无法使用聚合选项参数获得结果。这是我的聚合:-

var emails = getAllEmails();
var listMatchColl = 'list_matches_' + insertedId;
SurveyDL.aggregate([
     { $match: { email: { $in: emails } } },
     { $out: listMatchColl }
 ], {
   allowDiskUse: true
 }).exec(function(err, data) {
  if (err) return console.log('err', err);
    console.log('data',data);
 });
}

当我执行上面的代码时,它会抛出错误,即,

错误:参数必须是聚合管道运算符 在 Aggregate.append (/home/vivek/nrich/node_modules/mongoose/lib/aggregate.js:89:11) 在新聚合处 (/home/vivek/nrich/node_modules/mongoose/lib/aggregate.js:48:17)

我也使用了另一种方法,但它仍然抛出同样的错误。替代方式:-

var emails = getAllEmails();
var listMatchColl = 'list_matches_' + insertedId;
SurveyDL.aggregate([
     { $match: { email: { $in: emails } } },
     { $out: listMatchColl }
 ], {
   allowDiskUse: true
 },function(err, data) {
  if (err) return console.log('err', err);
    console.log('data',data);
 });

【问题讨论】:

    标签: node.js mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    var emails 必须是 Array

    listMatchColl 必须是 字符串

    { $out: 'listMatchColl' }
    

    如果你使用 $out,你将看不到你的聚合结果。 您在新集合“listMatchColl”中的结果。

    【讨论】:

    • 实际上,listMatchColl 动态创建。我有更新的问题请检查。
    • 但它会抛出错误Error: Arguments must be aggregate pipeline operators at Aggregate 并且无法创建集合。
    • emails=['abc@gmail.com','xyz@gmail.com',.....]' 一样,我的emails 变量中还有大约900000 的值。我认为我在这里遗漏了一些东西。
    • 对不起,我不能重复同样的错误。尝试用小数组聚合,因为我运行相同的聚合并得到结果。
    • /node_modules/mongoose/lib/aggregate.js:574 console.log(k),你必须只有 [ '$match' ] [ '$out' ]。如果您有其他值,我认为您需要编辑您的查询
    【解决方案2】:

    尝试为聚合查询设置 allowDiskUse() 选项:

    var emails = getAllEmails();
    var listMatchColl = 'list_matches_' + insertedId;
    SurveyDL.aggregate([
        { '$match': { 'email': { '$in': emails } } },
        { '$out': listMatchColl }
     ]).allowDiskUse(true)
       .exec(function(err, data) {
            if (err) return console.log('err', err);
            console.log('data',data);
        }); 
    

    或使用流畅的 API:

    SurveyDL.aggregate()
            .match({ 'email': { '$in': emails } })
            .append({ '$out': listMatchColl })
            .allowDiskUse(true)
            .exec(function(err, data) {
                if (err) return console.log('err', err);
                console.log('data',data);
            });
    

    您可能会超过 16MB 的聚合大小 limit,如果您的数据大于 16MB,则 allowDiskUse() 选项是不够的,因为它只允许您在数据很大时使用排序.考虑使用聚合 cursor 表单来访问您的聚合文档:

    var cursor = SurveyDL.aggregate([
        { $match: { email: { $in: emails } } }    
     ]).cursor({ batchSize: 1000 }).exec();
    
    cursor.each(function(error, doc) {
      // use doc
    }); 
    

    【讨论】:

    • 感谢@chridam 的回复,但我仍然遇到问题。现在它抛出错误MongoError: attempt to write outside buffer bounds。我的 mongodb 版本是 3.2.6,猫鼬是 4.1.2,我正在使用 bluebird
    • @vineetsahCL 添加了另一个选项。
    • 通过使用cursor我得到了错误,即RangeError: attempt to write outside buffer bounds
    • 实际上我上传了一个大约 20mb 的 csv 文件,其中包含大约 900000 封电子邮件。
    猜你喜欢
    • 2019-03-27
    • 2017-08-24
    • 2014-12-11
    • 2021-06-16
    • 2018-04-24
    • 1970-01-01
    • 2021-06-12
    • 2018-04-22
    • 2017-06-18
    相关资源
    最近更新 更多