首页 > 解决方案 > 按文档字段对字典值进行分组

问题描述

我有一个集合,其中每个文档都包含一个字典和其他字段。我想按字段之一对字典进行分组,level.

示例集合:

{
    level: 1
    votes: {
            name1: 1
            name3: -1
            }
}
{
    level: 2
    votes: {
            name4: 1
            name1: 1
            }
}
{
    level: 1
    votes: {
            name1: 1
            name3: 1
            name4: -1
            }
}

预期输出:

{
    level: 1
    votes: {
            name1: 2
            name3: 0
            name4: -1
            }
}
{
    level: 2
    votes: {
            name4: 1
            name1: 1
            }
}

我能找到的所有例子都做了我想做的事情,但是我有一本字典,我不确定我是否可以使用unwind它,或者我什至应该使用它。

这可以在 pymongo/mongodb 中完成,还是我必须在本机 python3 中完成?

谢谢您的帮助。

标签: mongodbpymongo

解决方案


我们首先需要将“votes”对象转换为数组,对其进行处理,然后再次将其转换为对象。以下查询可以获得预期的输出:

db.collection.aggregate([
    {
        $addFields:{
            "votes":{
                $objectToArray:"$votes"
            }
        }
    },
    {
        $unwind:"$votes"
    },
    {
        $group:{
            "_id":{
                "level":"$level",
                "k":"$votes.k"
            },
            "level":{
                $first:"$level"
            },
            "k":{
                $first:"$votes.k"
            },
            "v":{
                $sum:"$votes.v"
            }
        }
    },
    {
        $project:{
            "level":1,
            "votes.k":"$k",
            "votes.v":"$v"
        }
    },
    {
        $group:{
            "_id":"$level",
            "level":{
                $first:"$level"
            },
            "votes":{
                $push:"$votes"
            }
        }
    },
    {
        $project:{
            "_id":0,
            "level":1,
            "votes":{
                $arrayToObject:"$votes"
            }
        }
    }
]).pretty()

输出:

{ "level" : 2, "votes" : { "name4" : 1, "name1" : 1 } }
{ "level" : 1, "votes" : { "name4" : -1, "name1" : 2, "name3" : 0 } }

推荐阅读