【问题标题】:Mongodb group by inner elementMongodb按内部元素分组
【发布时间】:2021-12-20 00:24:08
【问题描述】:

我用一个简单的例子来解释我的 mongodb 集合看起来像这样, [

    {
        pid: erwer,
        qty: 3,
        LevelDetails: {
            level1: { userId: 1, amount: 10 },
            level2: { userId: 2, amount: 20 },
            level3: { userId: 3, amount: 13 },
        }
    },
    {
        pid: qwsdfg,
        qty: 1,
        LevelDetails: {
            level1: { userId: 1, amount: 10 },
            level2: { userId: 4, amount: 20 },
            level3: { userId: 3, amount: 13 },
        }
    },

]

从集合中,我需要每个用户的级别 1、级别 2 和级别 3 的总和。 查询结果应该是这样的 [

        { userId1: { TotalLevel1Amount: 20, TotalLevel2Amount: 0, TotalLevel3Amount: 0 } },

        { userId2: { TotalLevel1Amount: 0, TotalLevel2Amount: 20, TotalLevel3Amount: 0 } },

        { userId3: { TotalLevel1Amount: 0, TotalLevel2Amount: 0, TotalLevel3Amount: 26 } },

        { userId4: { TotalLevel1Amount: 0, TotalLevel2Amount: 20, TotalLevel3Amount: 0 } }
    ]

【问题讨论】:

    标签: database mongodb go nosql aggregation-framework


    【解决方案1】:
    1. $set:通过将 LevelDetails 转换为键值对来添加新字段 _levelDetails
    2. $unwind:解构_levelDetails数组。
    3. $group:根据级别 (_levelDetails.k) 有条件地按 _levelDetails.v.userId$sum 分组。
    4. $project: 格式化显示的文档。
    5. $sort(可选):按userID升序排序。
    db.collection.aggregate([
      {
        $set: {
          _levelDetails: {
            $objectToArray: "$LevelDetails"
          }
        }
      },
      {
        $unwind: "$_levelDetails"
      },
      {
        $group: {
          _id: "$_levelDetails.v.userId",
          "TotalLevel1Amount": {
            $sum: {
              $cond: [
                {
                  "$eq": [
                    "$_levelDetails.k",
                    "level1"
                  ]
                },
                "$_levelDetails.v.amount",
                0
              ]
            }
          },
          "TotalLevel2Amount": {
            $sum: {
              $cond: [
                {
                  "$eq": [
                    "$_levelDetails.k",
                    "level2"
                  ]
                },
                "$_levelDetails.v.amount",
                0
              ]
            }
          },
          "TotalLevel3Amount": {
            $sum: {
              $cond: [
                {
                  "$eq": [
                    "$_levelDetails.k",
                    "level3"
                  ]
                },
                "$_levelDetails.v.amount",
                0
              ]
            }
          }
        }
      },
      {
        $project: {
          _id: 0,
          userId: "$_id",
          TotalLevel1Amount: 1,
          TotalLevel2Amount: 1,
          TotalLevel3Amount: 1
        }
      },
      {
        $sort: {
          userId: 1
        }
      }
    ])
    

    Sample Mongo Playground


    至键值对:{ 'userId': { // Result } }

    步骤 1 到 3 与之前的解决方案相同。

    1. $sort(可选):按_id升序排序。
    2. $project:显示带有array 字段的文档(带有属性kv)。
    3. $replaceRoot:将整个文档替换为键(userId)和值(结果)。
    db.collection.aggregate([
      {
        $set: {
          _levelDetails: {
            $objectToArray: "$LevelDetails"
          }
        }
      },
      {
        $unwind: "$_levelDetails"
      },
      {
        $group: {
          _id: "$_levelDetails.v.userId",
          "TotalLevel1Amount": {
            $sum: {
              $cond: [
                {
                  "$eq": [
                    "$_levelDetails.k",
                    "level1"
                  ]
                },
                "$_levelDetails.v.amount",
                0
              ]
            }
          },
          "TotalLevel2Amount": {
            $sum: {
              $cond: [
                {
                  "$eq": [
                    "$_levelDetails.k",
                    "level2"
                  ]
                },
                "$_levelDetails.v.amount",
                0
              ]
            }
          },
          "TotalLevel3Amount": {
            $sum: {
              $cond: [
                {
                  "$eq": [
                    "$_levelDetails.k",
                    "level3"
                  ]
                },
                "$_levelDetails.v.amount",
                0
              ]
            }
          }
        }
      },
      {
        $sort: {
          _id: 1
        }
      },
      {
        $project: {
          array: [
            {
              k: {
                $toString: "$_id"
              },
              v: {
                TotalLevel1Amount: "$TotalLevel1Amount",
                TotalLevel2Amount: "$TotalLevel2Amount",
                TotalLevel3Amount: "$TotalLevel3Amount"
              }
            }
          ]
        }
      },
      {
        "$replaceRoot": {
          newRoot: {
            $arrayToObject: "$array"
          }
        }
      }
    ])
    

    Sample Mongo Playground (To Key-Value Pair)

    【讨论】:

      猜你喜欢
      • 2014-02-25
      • 2021-12-22
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      相关资源
      最近更新 更多