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

能否通过Mongo的$group实现指定数据转换,还是需客户端JS处理?

用MongoDB聚合实现按id分组并将lib转为带序号的字段结构
  • 完全可以通过MongoDB的聚合管道实现,不需要在客户端用JavaScript处理

核心逻辑分三步:先把同一id下的所有lib值收集成数组,再把数组转换成lib_1、lib_2这类带序号的键值对,最后把这些键值对合并到主文档里。

示例操作

假设你的原始数据是这样的:

[
  { id: 1, lib: "A" },
  { id: 1, lib: "B" },
  { id: 2, lib: "C" },
  { id: 2, lib: "D" },
  { id: 2, lib: "E" }
]

执行以下聚合命令:

db.collection.aggregate([
  // 按id分组,把同id的lib攒成数组
  {
    $group: {
      _id: "$id",
      libs: { $push: "$lib" }
    }
  },
  // 将数组转成lib_1、lib_2格式的键值对对象
  {
    $addFields: {
      libFields: {
        $arrayToObject: {
          $map: {
            input: "$libs",
            as: "item",
            in: {
              k: { $concat: ["lib_", { $toString: { $add: [{ $indexOfArray: ["$libs", "$$item"] }, 1] } }] },
              v: "$$item"
            }
          }
        }
      }
    }
  },
  // 把生成的字段合并到根文档,清理临时字段
  {
    $replaceRoot: {
      newRoot: { $mergeObjects: ["$$ROOT", "$libFields"] }
    }
  },
  {
    $project: { libs: 0, libFields: 0 }
  }
])

最终结果

[
  { _id: 1, lib_1: "A", lib_2: "B" },
  { _id: 2, lib_1: "C", lib_2: "D", lib_3: "E" }
]

额外说明

  • 索引加1是为了让序号从1开始(默认数组索引从0),如果不需要可以去掉$add里的1
  • 要是想把_id改回原来的id字段,在最后加一步:
    { $addFields: { id: "$_id" }, $project: { _id: 0 } }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:20:38