Mongodb 按文档字段对字典值进行分组

Mongodb 按文档字段对字典值进行分组,mongodb,pymongo,Mongodb,Pymongo,我有一个集合,其中每个文档都包含一个字典和其他字段。我想按一个字段对字典进行分组,level 示例集合: { level: 1 votes: { name1: 1 name3: -1 } } { level: 2 votes: { name4: 1 name1: 1 } } { level: 1 votes

我有一个集合,其中每个文档都包含一个字典和其他字段。我想按一个字段对字典进行分组,
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
            }
}
预期输出:

{
    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
            }
}
我能找到的所有例子都是我想在列表上做的,但我有一本字典,我不确定我是否可以使用
展开
,或者我是否应该这样做

这可以在pymongo/mongodb中完成,还是必须在原生python3中完成


感谢您的帮助。

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

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 } }

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

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 } }

我必须向所有
$
-变量添加
,以使其在pymongo中工作。不幸的是,结果不正确:
[{'level':2,'devots':{'name1':1,'name4':1},{'level':1,'devots':{'name3':-1,'name1':2,'name4':-1}]
澄清一下:你得到了
name3=1
,我得到了
name3=-1
,但它应该是
0
。这很有效,谢谢。你能详细说明一下变化吗?@dakes我在级别、键和值上分组,但它只在级别和键上是必需的。我必须将
添加到所有
$/code>-变量中,才能在pymongo中工作。不幸的是,结果不正确:
[{'level':2,'投票':{'name1':1,'name4':1}},{'level':1,'投票':{'name3':-1,'name1':2,'name4':-1}]
澄清一下:你得到了
name3=1
,我得到了
name3=-1
,但它应该是
0
。谢谢。你能详细说明一下变化吗?@dakes我是按级别、键和值分组的,但只要求按级别和键分组。