将对象数组转换为该对象的值数组

时间:2021-06-24 19:53:30

标签: mongodb mongodb-query

我的收藏中有以下文档:

{
  "archives" : [ 
    { "colour" : "red", "default" : true }, 
    { "colour" : "green", "default" : false }
  ]
}
{
  "archives" : [ 
    { "colour" : "yellow", "default" : true } 
  ] 
}

我想从存档对象中投影颜色值,如下所示:

{
  "archives" : [ "red", "green" ]
}
{
  "archives" : [ "yellow" ] 
}

我的提议

我最好的尝试是这个查询:

db.test.find({}, {
    'archives': {
        '$map': {
            'input': '$archives', 
            'in': '$archives.colour'
         }
     }
})

但它返回一个包含冗余信息的数组,如下所示:

{ "archives" : [ [ "red", "green" ], [ "red", "green" ] ] }
{ "archives" : [ [ "yellow" ] ] }

那么,给出我需要的结果的正确查询是什么,最好是在数据库端,并且尽可能高效?

2 个答案:

答案 0 :(得分:2)

您可以使用聚合框架:

$unwind

$group

db.test.aggregate([
  {
    "$unwind": "$archives"
  },
  {
    "$group": {
      "_id": "$_id",
      "archives": {
        "$push": "$archives.colour"
      }
    }
  }
])

Playground

如果您不想在输出中包含 _id,您可以通过添加额外的 $project 阶段来排除它:

db.test.aggregate([
  {
    "$unwind": "$archives"
  },
  {
    "$group": {
      "_id": "$_id",
      "archives": {
        "$push": "$archives.colour"
      }
    }
  },
  {
    "$project": {
      _id: 0
    }
  }
])

答案 1 :(得分:2)

为什么不简单:

db.test.aggregate([
   { $set: { archives: "$archives.colour" } }
])

如果您喜欢使用 $map,那么就是这个。您错过了 $$this 变量:

db.test.aggregate([
  {
    $set: {
      archives: {
        "$map": {
          "input": "$archives",
          "in": "$$this.colour"
        }
      }
    }
  }
])

db.test.aggregate([
  {
    $set: {
      archives: {
        "$map": {
          "input": "$archives.colour",
          "in": "$$this"
        }
      }
    }
  }
])