首页 > 解决方案 > MongoDB 按键和值聚合映射

问题描述

我想按键聚合以下内容并对值求和:

{
    "_id": {
        "$oid": "60dd5e0bd0ba24343dabc626"
    },
    "s": {
        "_71vnohpi4": {
            "q": 2
        }
    }
},
{
    "_id": {
        "$oid": "609ea0b0c85ca8e54adc610c"
    },
    "s": {
        "_71vnohpi4": {
            "q": 49
        },
        "_h2121audz": {
            "q": 20
       }
    }
}

想总结如下的价值:

{
    "_id": {
        "$oid": "newid-doesntmatter"
    },
    "s": {
        "_71vnohpi4": {
            "q": 51
        },
        "_h2121audz": {
            "q": 20
       }
    }
}

大多数可用的示例都适用于数组,因此$unwind在我的情况下不起作用。而且由于键是动态的,我无法指定键名。

这是我尝试过的,但我无法对键进行分组。 试过了

标签: mongodbaggregation-framework

解决方案


有聚合运算符,例如$objectToArrayand $arrayToObject

  1. 将对象转换为数组(键值对)

  2. 展开以拆分为单独的文档。

  3. 再次将值 Object 转换为数组,因为它又是一个对象。

  4. 再次放松

  5. 基于id和的组key(这将给出总和)

  6. 分组阶段以组合最内部的键/值。

  7. 组合所有文件的小组阶段。

  8. $arrayToObject用于到达单个对象的项目。

    [{
    '$project': {
            's': {
                '$objectToArray': '$s'
            }
        }
    }, {
        '$unwind': '$s'
    }, {
       '$addFields': {
            's-v': {
                '$objectToArray': '$s.v'
            }
        }
    }, {
        '$unwind': '$s-v'
    }, {
        '$group': {
            '_id': {
                'id': '$s.k',
                'key': '$s-v.k'
            },
            'stats': {
                '$sum': '$s-v.v'
            }
        }
    }, {
        '$group': {
            '_id': '$_id.id',
            'sum': {
                '$mergeObjects': {
                    '$arrayToObject': [
                        [
                            [
                                '$_id.key', '$stats'
                            ]
                        ]
                    ]
                }
            }
        }
    }, {
        '$group': {
            '_id': '1',
            'obj': {
                '$push': {
                    'k': '$_id',
                    'v': '$sum'
                 }
             }
         }
    }, {
        '$project': {
            'final': {
                '$arrayToObject': '$obj'
            }
        }
    }]
    

推荐阅读