按文档字段分组字典值

时间:2019-08-09 07:18:10

标签: mongodb pymongo

我有一个集合,其中每个文档都包含一个词典和其他字段。我想按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中完成?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

我们首先需要将“ 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 } }