You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MongoDB中根据元素属性将数组元素数据聚合到单个元素中

解决MongoDB嵌套数组按qId分组聚合的问题

嘿,我懂你这种卡壳的感觉——看起来你是想处理嵌套在qData数组里的、按qId分组的数据对吧?先把你的示例数据整理清楚,方便咱们看:

// 你的MongoDB文档示例
[
  {
    "_id": ObjectId("5ad078cc43c90bb8118b457b"),
    "totalTime": 323,
    "qData": [
      { "qId": "123456", "weight": 38 },
      { "qId": "654321", "age": 21 },
      { "qId": "123456", "age": 14 },
      { "qId": "654321", "height": 122 },
      { "qId": "654321", "weight": 34 }
    ]
  },
  {
    "_id": ObjectId("5ad084cc43c90bb8118b4583"),
    "totalTime": 312,
    "qData": [
      { "qId": "123456", "weight": 42 }
      // 省略的部分默认是同结构数据
    ]
  }
]

我猜你大概率是想把所有qData里的元素按qId归类,聚合每个qId对应的所有属性值?下面给你两种常见场景的解决方案:

场景1:按qId聚合所有属性,相同属性值存为数组

这个方案会把同一个qId下的所有属性(比如weight、age)都收集起来,相同属性的多个值放到数组里:

db.yourCollection.aggregate([
  // 拆分数组,把每个qData元素变成独立文档
  { $unwind: "$qData" },
  // 按qId分组,收集所有非qId的属性键值对
  {
    $group: {
      _id: "$qData.qId",
      attributes: {
        $push: {
          $arrayToObject: {
            $filter: {
              input: { $objectToArray: "$qData" },
              cond: { $ne: ["$$this.k", "qId"] }
            }
          }
        }
      }
    }
  },
  // 把收集到的属性合并成清晰的结构,相同属性值用数组存储
  {
    $project: {
      _id: 0,
      qId: "$_id",
      details: {
        $reduce: {
          input: "$attributes",
          initialValue: {},
          in: {
            $mergeObjects: [
              "$$value",
              {
                $arrayToObject: {
                  $map: {
                    input: { $objectToArray: "$$this" },
                    as: "attr",
                    in: {
                      k: "$$attr.k",
                      v: {
                        $concatArrays: [
                          { $ifNull: ["$$value.$$attr.k", []] },
                          ["$$attr.v"]
                        ]
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

执行后你会得到类似这样的结果:

[
  {
    "qId": "123456",
    "details": { "weight": [38, 42], "age": [14] }
  },
  {
    "qId": "654321",
    "details": { "age": [21], "height": [122], "weight": [34] }
  }
]

场景2:按qId聚合特定属性的统计值(比如weight总和)

如果你的需求更具体,比如只想算每个qId的weight总和,同时收集age和height的值,可以用这个简化版:

db.yourCollection.aggregate([
  { $unwind: "$qData" },
  {
    $group: {
      _id: "$qData.qId",
      totalWeight: { $sum: { $ifNull: ["$qData.weight", 0] } },
      ageList: { $push: { $ifNull: ["$qData.age", null] } },
      heightList: { $push: { $ifNull: ["$qData.height", null] } }
    }
  },
  // 整理输出结构,去掉默认的_id,换成qId
  { $project: { _id: 0, qId: "$_id", totalWeight: 1, ageList: 1, heightList: 1 } }
])

这个查询的结果会更简洁,适合有明确统计需求的场景。

要是你的需求不是这两种,随时补充细节,我再帮你调整!

内容的提问来源于stack exchange,提问作者JohnPan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:39:26