按文件内的数组中的键分组

时间:2016-12-28 17:06:01

标签: mongodb aggregation-framework

我是MongoDB中的新手,我在mongo中有一个这种结构的文档:

{    
"game" : "chess",
"name" : "Chess",
"prizes" : [ 
    {
        "_id" : ObjectId("562575c61d41c81efce7bc1b"),
        "group" : 0,
        "name" : "10 coins",
        "pos" : "0",
    },
    {
        "_id" : ObjectId("562575c61d41c81efce7bc1c"),
        "group" : 0,
        "name" : "10 coins",
        "pos" : "1",
    }, 
    {
        "_id" : ObjectId("562575c61d41c81efce7bc1d"),
        "group" : 1,
        "name" : "20 coins",
        "pos" : "2",
    }, 
}

我需要得到一些这样的东西:

{    
"game" : "chess",
"name" : "Chess",
"prizes" : [ 
    {
        "name" : "10 coins",
        "group" : 0,
    },
    {
        "name" : "20 coins",
        "group" : 1,
    }

我尝试使用聚合和投影并放松但我没有得到我需要的结构,谢谢。

2 个答案:

答案 0 :(得分:1)

基本上我正在放松,然后根据您想要的问题输出将奖品数组缩小到您想要的字段。然后使用游戏和名称将它们全部组合在一起,并使用$ addToSet将唯一的组和名称插入到数组中。我假设没有重复的游戏,但我认为它无论如何都会起作用,因为他们只会聚在一起。

db.docs.aggregate([
   {$unwind : '$prizes'},
   {$project: {name: '$name', game: '$game', prizes: {group: '$prizes.group', name: '$prizes.name'}}},
   {$group: {_id: {name: '$name', game: '$game'}, prizes: {$addToSet: '$prizes'}}},
])

答案 1 :(得分:0)

您可以尝试如下。使用$ map和一些set操作$ setUnion或$ setDifference,只需要在转换形状时过滤重复项。

aggregate([{
    "$project": {
        "game": 1,
        "name": 1,
        "prizes": {
            "$setUnion": [{
                    "$map": {
                        "input": "$prizes",
                        "as": "prize",
                        in: {
                            "name": "$$prize.name",
                            "group": "$$prize.group"
                        }
                    }
                },
                []
            ]
        }
    }
}]).pretty();