【问题标题】:Aggregate pipeline throws the error "A pipeline stage specification object must contain exactly one field."聚合管道引发错误“管道阶段规范对象必须只包含一个字段。”
【发布时间】:2017-09-20 21:28:45
【问题描述】:
db.audiofiles.aggregate({
    $match: {
        privacy: { $ne: "same" },
        date: { "$eq": "2017/04/25" },
        deleted: 0
    },
    $group: { "_id": "$to_email" }
});

我使用了$match,但它仍然显示如下管道错误。

assert: command failed: {
    "ok" : 0,
    "errmsg" : "A pipeline stage specification object must contain exactly one field.",
    "code" : 16435
} : aggregate failed

【问题讨论】:

  • 管道是一个数组。在括号之间添加方括号。
  • db.audiofiles.aggregate({[$match:{privacy:{$ne:"same"},date:{"$eq": "2017/04/25" },deleted: 0]},$group:{"_id":"$to_email"}});出现错误,例如 -> 2017-04-24T14:46:37.021+0530 E QUERY [thread1] SyntaxError: missing ] in computed property name @(shell):1:32

标签: mongodb mongodb-query aggregation-framework database


【解决方案1】:

您需要将管道阶段放在array 中,即文档按顺序通过这些阶段。

db.collection.aggregate( [ { <stage> }, ... ] )

$group 管道步骤运算符应位于其自己的对象/文档中,而不是作为 $match 管道步骤的一部分。你聚合管道应该是

db.audiofiles.aggregate([
    /* match pipeline */
    {
        "$match": {
            "privacy": { "$ne": "same" },
            "date": { "$eq": "2017/04/25" },
            "deleted": 0
        }
    },
    /* group pipeline */
    {
        "$group": { 
            "_id": "$to_email", 
            "count": { "$sum": 1 }
        }
    }
]);

或者将管道步骤创建为可以推送到数组的对象变量,并且该数组成为管道以用作 aggregate() 方法参数:

/* match pipeline */
var match = {
    $match: {
        privacy: { $ne: "same" },
        date: { "$eq": "2017/04/25" },
        deleted: 0
    }
},
/* group pipeline */
group = {
    $group: { 
        "_id": "$to_email", 
        "count": { "$sum": 1 }
    }
};

db.audiofiles.aggregate([match, group]);

如果您没有从上面得到任何响应,请尝试仅一步运行聚合管道:

db.audiofiles.aggregate([match]);

匹配步骤的结果将通过管道传送到下一阶段,因此如果您没有得到任何结果,则意味着 $match 管道步骤未找到任何匹配的文档。改一些参数看看有没有结果。

【讨论】:

  • 在我的 mongo 终端中输入上述查询时没有得到任何响应?
  • 那么这意味着您的$match 管道没有返回任何匹配项,或者您正在对错误的集合运行聚合操作。使用$match 管道尝试不同的参数进行调试,或者只使用$group 步骤运行管道,看看它是否返回任何文档。
  • audiofiles.aggregate({$group:{"_id":"$to_email"} });如果我输入上面的查询,我将从我的收藏中获取记录.. audiofiles.find({privacy:{$ne:"same"},date:{"$eq":"24/04/2017" },deleted :0}})。如果我输入上面的查询,我会得到一组响应..
  • 那么db.audiofiles.aggregate([match]); 应该返回与db.audiofiles.find({privacy:{$ne:"same"},date:{"$eq":"24/04/201‌​7" },deleted:0}}) 相同的响应集,因为$match 使用标准的MongoDB 查询。如果可行,那么您应该可以将下一个 $group 步骤添加到管道 db.audiofiles.aggregate([match, group]);
  • 完美运行 :) 谢谢
【解决方案2】:

我也遇到了同样的错误。 我的代码是:

 db.getCollection('users').aggregate([
      {
          "$lookup":
          {     
              from: 'songs',
              localField: '_id',
              foreignField: 'artistId',              
              as: 'abc'              
          },
          "$project":
          {
              "name":1,
              "status":1,
              "abc":{"artistId":1, "name":1}
          }
      }
])

我通过添加 { } 解决了。

db.getCollection('users').aggregate([
      {
          "$lookup":
          {     
              from: 'songs',
              localField: '_id',
              foreignField: 'artistId',              
              as: 'abc'              
          }
      }, // added braces
      { 
          "$project":
          {
              "name":1,
              "status":1,
              "abc":{"artistId":1, "name":1}
          }
      } // added braces
])

注意:: 确保 $lookup 和 $project 应该在不同的 {} 大括号中,例如:

db.getCollection('users').aggregate([ { $lookup:{} }, { $project: {} } ])

我的代码是:

 db.getCollection('users').aggregate([ { $lookup:{},  $project: {} } ])

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 2020-02-04
    • 2016-12-27
    • 2013-12-08
    • 2017-07-17
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 2019-06-03
    相关资源
    最近更新 更多