【问题标题】:Get first element in array and return using Aggregate?获取数组中的第一个元素并使用聚合返回?
【发布时间】:2015-01-01 23:32:12
【问题描述】:

如何使用 Mongo 聚合获取和返回数组中的第一个元素?

我尝试使用此代码:

db.my_collection.aggregate([
    { $project: {
        resp : { my_field: { $slice: 1 } }
    }}
])

但我收到以下错误:

uncaught exception: aggregate failed: {
    "errmsg" : "exception: invalid operator '$slice'",
    "code" : 15999,
    "ok" : 0
}

注意'my_field'是一个有4个元素的数组,我只需要返回第一个元素。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    从 3.2 开始,我们可以使用$arrayElemAt 来获取数组中的第一个元素

    db.my_collection.aggregate([
        { $project: {
            resp : { $arrayElemAt: ['$my_field',0] }
        }}
    ])
    

    【讨论】:

      【解决方案2】:

      目前,$slice 运算符在聚合管道的 $project 操作中不可用。 所以你可以做的是,

      首先$unwindmy_field 数组,然后将它们组合在一起并取组的$first 元素。

      db.my_collection.aggregate([
      {$unwind:"$my_field"},
      {$group:{"_id":"$_id","resp":{$first:"$my_field"}}},
      {$project:{"_id":0,"resp":1}}
      ])
      

      或者使用find() 命令,您可以在projection 部分使用$slice 运算符。

      db.my_collection.find({},{"my_field":{$slice:1}})
      

      更新:根据您的 cmets,假设您只需要数组中的 second 项,用于 ID 为 id 的记录。

      var field = 2;
      var id = ObjectId("...");
      

      然后,下面的聚合命令会为您提供 my_field 记录数组中的第二项,即 _idid

      db.my_collection.aggregate([
      {$match:{"_id":id}},
      {$unwind:"$my_field"},
      {$skip:field-1},
      {$limit:1}
      ])
      

      上面的逻辑不能应用于更多的记录,因为它会在$unwind之后涉及$group,运算符。 $group 运算符为该特定组中的所有记录生成单个记录,从而使在后期应用的 $limit$skip 运算符无效。

      上面的find() 查询的一个小变化也会产生预期的结果。

      db.my_collection.find({},{"my_field":{$slice:[field-1,1]}})
      

      除此之外,总有办法在客户端做到这一点,但如果记录数量很大,成本会有点高:

      var field = 2; 
      db.my_collection.find().map(function(doc){
      return doc.my_field[field-1];
      })
      

      从上述选项中进行选择取决于您的数据大小和应用设计。

      【讨论】:

      • 不幸的是,您回答了我的问题却没有解决我的问题。我需要一个通用聚合,其中一个参数定义我将返回$my_field 的哪个元素。我尝试添加$skip,但它不是$group 运算符。
      • 查看我的更新答案。无论如何,我认为我最初的帖子已经回答了你的问题。如果您需要更多说明,您可以随时更新您的问题或添加新问题。
      【解决方案3】:

      $slice 运算符计划在 Mongo 3.1.4 的 $project 操作中可用,根据这张票:https://jira.mongodb.org/browse/SERVER-6074

      这将使问题消失。

      此版本目前只是开发者版本,还不稳定(截至 2015 年 7 月)。预计在 10 月/11 月左右。

      【讨论】:

        【解决方案4】:

        Mongo 3.1.6 以后,

        db.my_collection.aggregate([
        { 
            "$project": {
                "newArray" : { "$slice" : [ "$oldarray" , 0, 1 ] }
            }
        }
        ])
        

        其中0 是起始索引,1 是要切片的元素数

        【讨论】:

          【解决方案5】:

          Mongo 4.4开始,聚合运算符$first可用于访问数组的第一个元素:

          // { "my_field": ["A", "B", "C"] }
          // { "my_field": ["D"] }
          db.my_collection.aggregate([
            { $project: { resp: { $first: "$my_field" } } }
          ])
          // { "resp" : "A" }
          // { "resp" : "D" }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-10-31
            • 2019-11-19
            • 1970-01-01
            • 2011-05-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多