首页 > 解决方案 > mongoose 聚合和求和嵌套的 OBJECT (NOT ARRAY ) 字段

问题描述

我看过很多使用嵌套字段的帖子aggregatesumARRAY尝试将它与我的嵌套对象一起使用,但它不起作用。

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

[
        {
            "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' } } }
    ]);

有人可以就如何做到这一点给我一些建议和建议吗?

提前致谢。

标签: mongodbmongoosesumaggregate

解决方案


这里发生了一些事情:

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


推荐阅读