首页 文章

MongoDB聚合嵌套分组

提问于
浏览
2

我有资产收集,其中包含数据

{
     "_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 回答

  • 1

    使用MongoDb 3.6及更高版本,您可以在 $mergeObjects 表达式和 $replaceRoot 管道中使用 $arrayToObject 运算符来获得所需的结果 .

    您需要运行以下聚合管道:

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

    使用上面的示例文档 .

  • 1

    你必须在这里使用$group几次 . 首先使用 userssource 并使用$sum计算总字节数 .

    第二个是 users$push sourcebytes 成一个数组

    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"
          }
        }
      }}
    ])
    

    即使您想将 sourcebytes 转换为键值格式,然后使用以下两个阶段替换最后的 $group 阶段 .

    { "$group": {
      "_id": "$_id.users",
      "data": {
        "$push": {
          "k": "$_id.source",
          "v": "$bytes"
        }
      }
    }},
    { "$project": {
      "_id": 0,
      "username": "$_id",
      "bytes": { "$arrayToObject": "$data" }
    }}
    

相关问题