MongoDB聚合嵌套分组

时间:2018-12-09 05:29:15

标签: mongodb mongodb-query aggregation-framework

我有资产集合,其数据类似

{
     "_id" : ObjectId("5bfb962ee2a301554915"),
     "users" : [
                 "abc.abc@abc.com",
                 "abc.xyz@xyz.com"
          ],
     "remote" : {
                "source" : "dropbox",
                "bytes" : 1234
}
{
     "_id" : ObjectId("5bfb962ee2a301554915"),
     "users" : [
                 "pqr.pqr@pqr.com",
          ],
     "remote" : {
                "source" : "google_drive",
                "bytes" : 785
}
{
     "_id" : ObjectId("5bfb962ee2a301554915"),
     "users" : [
                 "abc.abc@abc.com",
                 "abc.xyz@xyz.com"
          ],
     "remote" : {
                "source" : "gmail",
                "bytes" : 5647
}

我要寻找的是按用户分组,并根据其来源获取字节总数

{
    "_id" : "abc.abc@abc.com",
    "bytes" : {
                 "google_drive": 1458,
                 "dropbox" : 1254
              }
}

我没有获得如何使用分组获取嵌套输出的信息。 我已经尝试过查询

db.asset.aggregate(
     [
        {$unwind : '$users'},
        {$group:{
                 _id:
                    {'username': "$users", 
                    'source': "$remote.source", 
                    'total': {$sum: "$remote.bytes"}} }
        }
    ]
)

通过这种方式,我得到了重复用户名的结果。

2 个答案:

答案 0 :(得分:1)

您必须在这里使用$group次。首先使用userssource,然后使用$sum计算字节总数。

然后将userssource的{​​{1}}和$push放入数组

bytes

即使您要将db.collection.aggregate([ { "$unwind": "$users" }, { "$group": { "_id": { "users": "$users", "source": "$remote.source" }, "bytes": { "$sum": "$remote.bytes" } }}, { "$group": { "_id": "$_id.users", "data": { "$push": { "source": "$_id.source", "bytes": "$bytes" } } }} ]) source转换为键值格式,也要用以下两个阶段替换最后一个bytes阶段。

$group

答案 1 :(得分:1)

在MongoDb 3.6及更高版本中,您可以在 $arrayToObject 表达式和 {{ 3}} 管道以获取所需的结果。

不过,您将需要运行以下聚合管道:

db.asset.aggregate([
    { "$unwind": "$users" },
    { "$group": {
        "_id": { 
            "users": "$users",
            "source": "$remote.source" 
        },
        "totalBytes": { "$sum": "$remote.bytes" }
    } },
    { "$group": {
        "_id": "$_id.users",
        "counts": {
            "$push": {
                "k": "$_id.source",
                "v": "$totalBytes"
            }
        }
    } },
    { "$replaceRoot": { 
        "newRoot": { 
            "$mergeObjects": [ 
                { "bytes": { "$arrayToObject": "$counts" } }, 
                "$$ROOT" 
            ] 
        } 
    } },
    { "$project": { "counts": 0 } }   
])

产生

/* 1 */
{
    "bytes" : {
        "gmail" : 5647.0,
        "dropbox" : 1234.0
    },
    "_id" : "abc.abc@abc.com"
}

/* 2 */
{
    "bytes" : {
        "google_drive" : 785.0
    },
    "_id" : "pqr.pqr@pqr.com"
}

/* 3 */
{
    "bytes" : {
        "gmail" : 5647.0,
        "dropbox" : 1234.0
    },
    "_id" : "abc.xyz@xyz.com"
}

使用上述示例文档。