如何在MongoDB的聚合管道中重新组合(或合并)对象?

时间:2020-11-09 22:05:59

标签: mongodb

我目前有一个聚合管道:

db.getCollection('forms').aggregate([
    { $unwind: //unwind },
    { 
        $match: {
            //some matches
        }   
    },
    {
        $project: {
            //some projections
        }
    }, 
    {        
        //Finally, im grouping the results
        $group: {
            _id: {
                year: { $year: '$createdAt' },
                month: { $month: '$createdAt' },
                raceEthnicity: '$demographic.raceEthnicity'
            },
            count: { $sum: 1 },
    }
]

我当前的结果类似于:

[{
    "_id" : {
        "year" : 2020,
        "month" : 11,
        "raceEthnicity" : "Asian"
    },
    "count" : 1.0
},
{
    "_id" : {
        "year" : 2020,
        "month" : 11,
        "raceEthnicity" : "Multiracial"
    },
    "count" : 3.0
},
{
    "_id" : {
        "year" : 2020,
        "month" : 11,
        "raceEthnicity" : "White"
    },
    "count" : 3.0
},
{
    "_id" : {
        "year" : 2020,
        "month" : 10,
        "raceEthnicity" : "White"
    },
    "count" : 33.0
}]

是否可以在管道上添加新阶段,以将同一年/月的结果“合并”到单个对象中? 我想实现以下目标:

{
    "_id" : {
        "year" : 2020,
        "month" : 11,
    },
    "Asian" : 1.0,
    "Multiracial": 3.0,
    "White": 1.0
},
{
    "_id" : {
        "year" : 2020,
        "month" : 10,
    },
    "White": 33
}

有可能吗?我该怎么办?

2 个答案:

答案 0 :(得分:1)

将此内容添加到您的聚合管道中。

db.collection.aggregate([
   { $set: { "data": { k: "$_id.raceEthnicity", v: "$count" } } },
   { $group: { _id: { year: "$_id.year", month: "$_id.month" }, data: { $push: "$data" } } },
   { $set: { "data": { $arrayToObject: "$data" } } },
   { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$data"] } } },
   { $unset: "data" }
])

与@ wak786中的解决方案不同,您不需要在设计时就了解所有种族。它适用于任意种族。

答案 1 :(得分:0)

将这些阶段添加到管道中。

db.collection.aggregate([
  {
    $replaceRoot: {
      newRoot: {
        "$mergeObjects": [
          "$$ROOT",
          {
            $arrayToObject: [
              [
                {
                  k: "$_id.raceEthnicity",
                  v: "$count"
                }
              ]
            ]
          }
        ]
      }
    }
  },
  {
    "$group": {
      "_id": {
        year: "$_id.year",
        month: "$_id.month",
        
      },
      "Asian": {
        "$sum": "$Asian"
      },
      "Multiracial": {
        "$sum": "$Multiracial"
      },
      "White": {
        "$sum": "$White"
      }
    }
  }
])

下面是mongo游乐场链接。我已将您管道的当前结果作为查询的输入。

尝试here