猫鼬聚合和求和嵌套的对象(非数组)字段

时间:2019-09-26 19:00:19

标签: mongodb mongoose sum aggregate

我看到很多关于使用aggregatesum嵌套ARRAY字段的帖子,我尝试将其与无法使用的嵌套对象一起使用。

查询时,数据结构类似于...

[
        {
            "key": "value",
            "more_key": "more_value",
            "meals": {
                "A": {
                    "name": "salmon",
                    "amount": "8"
                },
                "B": {
                    "name": "vege",
                    "amount": "6"
                },
            }
        },
        {
            "key": "value",
            "more_key": "more_value",
            "meals": {
                "A": {
                    "name": "salmon",
                    "amount": "8"
                },
                "B": {
                    "name": "vege",
                    "amount": "6"
                },
                "C": {
                    "name": "other meal",
                    "amount": "6"
                },
            }
        },
    ];

我正在尝试对amount

求和

我已经尝试过类似的事情...

await Model.aggregate([
        { $match: { isDeleted: false } },
        { $unwind: '$meals' },  // tried with + without this
        { $group: { _id: null, sum: { $sumA: '$meals.A.amount', $sumB: '$meals.B.amount' } } }
    ]);

有人可以给我一些建议和建议吗?

谢谢。

1 个答案:

答案 0 :(得分:2)

这里发生了一些事情:

1)$unwind不适用于对象,仅适用于数组。您可以通过使用$objectToArray

将餐对象转换为数组来解决此问题

2)您的金额字段看起来像是字符串类型,因此需要将其转换为数字以求和

这是满足您需要的聚合:

await Model.aggregate([
  // Convert meals object to array
  { $project: { meals: { $objectToArray: '$meals' }}},

  //  unwind meals array
  { $unwind:  '$meals' },

  // convert meals.v.amount to integer and sum them (the v is shorthand for values)
  { $group: { 
    _id: null, 
    total: {
      $sum: { 
        $convert: {
          input: '$meals.v.amount',
          to: 'int'
        }
      }
    }
  }}
])

您可以将$ group的_id更改为_id: meals.k,以便通过进餐对象(即A,B,C)的键进行求和