在 MongoDB $group 聚合中合并数组

Combine arrays in MongoDB $group aggregation

我正在使用 Mongo 每日分桶模式。每个每日文档都包含一个数组,其中包含当天每小时计算的值:

{
  meter: 'meterId',
  date: 'dailyBucket',
  hourlyConsumption: [0,0,1,1,1,2,2,2,4,4,4,4,3,3,3...] // array with 24 values for every hour of a day
}

现在,在我的一个聚合查询中,我想对同一天的多个仪表的文档进行分组,并得到如下结果:

INPUT(一天消耗多个电表)

{
  meter: 'MeterA',
  date: '2021-05-01',
  hourlyConsumption: [0,0,1,1,1,2,2,2,4,4,4,4,3,3,3...]
},
{
  meter: 'MeterB',
  date: '2021-05-01',
  hourlyConsumption: [10,10,10,10,10,10,10,10,10,10,10,10,10,10,10...]
}

RESULT(合并为单个文档)

{
  date: '2021-05-01',
  hourlyConsumption: [10,10,11,11,11,12,12,12,14,14,14,14,13,13,13...]
}

有没有不使用 $accumulator 就能实现的方法?

您可以使用$reduce

db.collection.aggregate([
  {
    $group: {
      _id: "$date",
      hourlyConsumption: { $push: "$hourlyConsumption" }
    }
  },
  {
    $set: {
      hourlyConsumption: {
        $reduce: {
          input: "$hourlyConsumption",
          initialValue: [],
          in: { $map: { input: { $range: [ 0, 23 ] },
              as: "h",
              in: {
                $sum: [ 
                  { $arrayElemAt: [ "$$value", "$$h" ] },
                  { $arrayElemAt: [ "$$this", "$$h" ] }
                ]
              }
            }
          }
        }
      }
    }
  }
])

Mongo Playground

或者您使用 $unwind$group:

db.collection.aggregate([
  {
    $unwind: {
      path: "$hourlyConsumption",
      includeArrayIndex: "hour"
    }
  },
  {
    $group: {
      _id: {
        date: "$date",
        hour: "$hour"
      },
      hourlyConsumption: { $sum: "$hourlyConsumption" }
    }
  },
  { $sort: { "_id.hour": 1 } },
  {
    $group: {
      _id: "$_id.date",
      hourlyConsumption: { $push: "$hourlyConsumption" }
    }
  }
])

Mongo Playground

然而,当你使用 $unwind 时,你实际上与你的分桶设计模式相矛盾。