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

MongoDB聚合:如何将文档按指定大小分组为等窗口/块

按固定数量分块聚合MongoDB文档

这个需求其实挺常见的——要把文档按固定数量打包成chunk,而不是按字段值分组。咱们可以通过$setWindowFields配合分组操作来实现,核心思路是先给每个文档分配一个连续的序号,再根据序号计算它所属的分组,最后按分组聚合收集_id即可。

针对你的示例数据,这里给出可以直接运行的聚合查询:

db.coll.aggregate([
  // 给每个文档添加连续行号,按_id排序保证顺序稳定
  {
    $setWindowFields: {
      partitionBy: null, // 全局范围不分区
      sortBy: { _id: 1 }, // 可根据业务需求替换其他排序字段
      output: {
        rowNumber: { $rowNumber: {} }
      }
    }
  },
  // 计算每个文档的分组键:每3个文档一组(实际替换为1024)
  {
    $set: {
      groupKey: { $floor: { $divide: [{ $subtract: ["$rowNumber", 1] }, 3] } }
    }
  },
  // 按分组键聚合,收集对应组的_id到chunk中
  {
    $group: {
      _id: "$groupKey",
      chunk: { $push: "$_id" }
    }
  },
  // 可选:移除分组键的_id,只保留chunk字段
  {
    $project: {
      _id: 0,
      chunk: 1
    }
  }
])

关键步骤解释:

  • $setWindowFields阶段:这个阶段用来给每个文档生成唯一连续的行号。partitionBy: null表示对整个集合的文档进行编号,sortBy必须指定(否则行号顺序是不确定的),这里用_id排序是比较稳妥的选择,你也可以换成业务上需要的排序字段。
  • 计算groupKey:通过$subtract把行号减1,再除以块大小(示例中是3)后取整,这样就能让每N个文档归为同一组——比如行号1-3会被分到groupKey=0,行号4-6分到groupKey=1,以此类推。
  • $group阶段:按groupKey分组,用$push把每组的_id收集到chunk数组里。
  • 可选的$project阶段:如果你不需要结果中的分组标识,这个阶段可以移除_id字段,让输出完全符合你想要的格式。

把示例中的3替换成1024,就能满足你实际的块大小需求啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:25:18