首页 > 解决方案 > 在聚合管道期间对列表索引进行平均?

问题描述

我目前有一个 MongoDB 聚合管道,它以以下类型的合成文档结束

[
    {
        '_id': '2019-09-10',
        'grouped_foos':
        [
            {... 'foo': [1, 78, 100]},
            {... 'foo': [8, 66, 98]},
            {... 'foo': [99, 5, 33]},
            {... 'foo': [120, 32, 2]}
        ]
    },
    {
        '_id': '2019-09-09',
        'grouped_foos':
        [
            {... 'foo': [10, 27]},
            {... 'foo': [19, 66]}
        ]
    },
    {
        '_id': '2019-09-08',
        'grouped_foos':
        [
            {... 'foo': [1]}
        ]
    }
]

我想继续这个管道并将foo列表的索引平均在一起以形成看起来像的文档

[
    {
        '_id': '2019-09-10',
        'avg_foo': [57, 45.25, 58.25]
    },
    {
        '_id': '2019-09-09',
        'avg_foo': [14.5, 46.5]
    },
    {
        '_id': '2019-09-08',
        'avg_foo': [1]
    }
]

在聚合期间是否可以进行这种类型的平均?我是否可能需要$unwind索引列表并分配新_id的唯一性以使文档看起来像

[
    {
        '_id': UUID,
        'old_id': '2019-09-10',
        'foo': 1,
        'index': 0
    },
    {
        '_id': UUID,
        'old_id': '2019-09-10',
        'foo': 78,
        'index': 1
    },
    ........
]

标签: mongodbaggregation-frameworkpymongo

解决方案


基本上你可以尝试$unwind但更简单和更快的方法是使用$reduce$map$sum中的所有行grouped_foos。然后你就可以运行另一个$map并使用$divide来获得平均值。

db.collection.aggregate([
    {
        $project: {
            size: { $size: "$grouped_foos" },
            foo_sum: {
                $reduce: {
                    input: "$grouped_foos",
                    initialValue: [],
                    in: {
                        $map: {
                            input: { $range: [ 0, { $size: "$$this.foo" }, 1 ] },
                            as: "index",
                            in: {
                                $add: [
                                    { $arrayElemAt: [ "$$this.foo", "$$index" ] },
                                    { $ifNull: [ { $arrayElemAt: [ "$$value", "$$index" ] }, 0 ] }
                                ]
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $project: {
            _id: 1,
            avg_foo: {
                $map: {
                    input: "$foo_sum",
                    in: {
                        $divide: [ "$$this", "$size" ]
                    }
                }
            }
        }
    }
])

蒙戈游乐场


推荐阅读