如何对集合进行分组以对对象的属性求和并使用 MongoDB 生成计算字段

问题描述 投票:0回答:1

如何按特定字段对集合进行分组并生成使用 mongoDB 对象的属性总和计算的字段,我不知道是否可以做我想做的事情,但我想知道.

我想按 duelId 字段分组以添加分数 收藏:

  {  "matches": [{
      "secondParticipant": {"name": "Maria","battlesWon": 2},
      "firstParticipant": {"name": "Fabio","battlesWon": 1},
      "duelId": "6c3e532d-3c0e-4438-8289-c86a4a51a102",
    },{
      "secondParticipant": {"name": "Fabio","battlesWon": 1 },
      "firstParticipant": {"name": "Maria","battlesWon": 1 },
      "duelId": "6c3e532d-3c0e-4438-8289-c86a4a51a102"
    },
    {
      "secondParticipant": {"name": "Luiz","battlesWon": 1},
      "firstParticipant": {"name": "Jose","battlesWon": 1},
      "duelId": "6c3e532d-3c0e-4438-8289-c86a4a51a666"
    }]}

预计:

 {[ [
      {
        "secondParticipant": {"name": "Maria","battlesWon": 2 },
        "firstParticipant": {"name": "Fabio","battlesWon": 1 },
        "duelId": "6c3e532d-3c0e-4438-8289-c86a4a51a102",
      },{
        "secondParticipant": {"name": "Fabio","battlesWon": 1},
        "firstParticipant": {"name": "Maria","battlesWon": 1},
        "duelId": "6c3e532d-3c0e-4438-8289-c86a4a51a102"
      },
      "score": { "Fabio": 2, "Maria": 3 } *// this field would be the sum of battlesWon after grouping*
    ], 
    [
      {
        "secondParticipant": {"name": "Luiz","battlesWon": 1},
        "firstParticipant": {"name": "Jose","battlesWon": 1},
        "duelId": "6c3e532d-3c0e-4438-8289-c86a4a51a666"
      },
      "score": { "Luiz": 1, "Jose": 1 } // *this field would be the sum of battlesWon after grouping*
    ]]}
mongodb mongoose mongodb-query
1个回答
2
投票

您可以执行以下操作:

  1. $unwind
    matches
    数组
  2. firstParticipant
    secondParticipant
    重命名为 k-v 元组数组以进行进一步处理
  3. 按决斗和姓名分组,总结每位参与者的分数
  4. 按决斗分组以获得每次决斗所请求的名称-分数元组
  5. 使用
    $arrayToObject
    将步骤 2 中的 k-v 元组数组转换回所请求的形式。
db.collection.aggregate([
  {
    "$unwind": "$matches"
  },
  {
    "$addFields": {
      "matches.participants": [
        {
          "k": "$matches.firstParticipant.name",
          "v": "$matches.firstParticipant.battlesWon"
        },
        {
          "k": "$matches.secondParticipant.name",
          "v": "$matches.secondParticipant.battlesWon"
        }
      ]
    }
  },
  {
    "$unwind": "$matches.participants"
  },
  {
    "$group": {
      "_id": {
        duel: "$matches.duelId",
        name: "$matches.participants.k"
      },
      "matches": {
        "$push": {
          duelId: "$matches.duelId",
          firstParticipant: "$matches.firstParticipant",
          secondParticipant: "$matches.secondParticipant"
        }
      },
      score: {
        $sum: "$matches.participants.v"
      }
    }
  },
  {
    "$group": {
      "_id": "$_id.duel",
      "matches": {
        "$first": "$matches"
      },
      "score": {
        $push: {
          k: "$_id.name",
          v: "$score"
        }
      }
    }
  },
  {
    "$addFields": {
      "score": {
        "$arrayToObject": "$score"
      }
    }
  }
])

这里是Mongo Playground供您参考。

© www.soinside.com 2019 - 2024. All rights reserved.