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

如何在MongoDB集合中按间隔提取指定位置的多个文档?

解决MongoDB提取每第10个文档的问题

你之前用$indexOfArray生成序号的方法逻辑错误,因为$$ROOT是单个文档对象,不是数组,$indexOfArray无法以此生成递增的行号。下面给你两种可行的解决方案:

方案一:使用$setWindowFields(MongoDB 5.0+推荐)

利用MongoDB 5.0新增的窗口函数$rowNumber可以直接生成全局递增的行号,效率更高:

db.your_collection_name.aggregate([
  // 先按timestamp排序,确保文档顺序稳定(必须指定排序,否则行号无意义)
  { $sort: { timestamp: 1 } },
  // 添加自增index字段
  {
    $setWindowFields: {
      partitionBy: null, // 不分区,整个集合作为一个窗口
      sortBy: { timestamp: 1 }, // 和排序阶段保持一致
      output: {
        index: { $rowNumber: {} } // 生成从1开始的行号
      }
    }
  },
  // 筛选每第10个文档
  { $match: { $expr: { $eq: [ { $mod: [ "$index", 10 ] }, 0 ] } } }
])

方案二:兼容旧版本MongoDB(低于5.0)

如果你的MongoDB版本不支持窗口函数,可以通过$group+$unwind的方式生成序号:

db.your_collection_name.aggregate([
  { $sort: { timestamp: 1 } },
  // 将所有文档存入一个数组
  { $group: { _id: null, docs: { $push: "$$ROOT" } } },
  // 展开数组并生成从0开始的索引
  {
    $unwind: {
      path: "$docs",
      includeArrayIndex: "index"
    }
  },
  // 因为索引从0开始,所以筛选第9、19...位(对应第10、20...个文档)
  { $match: { $expr: { $eq: [ { $mod: [ { $add: [ "$index", 1 ] }, 10 ] }, 0 ] } } },
  // 恢复原文档结构
  { $replaceRoot: { newRoot: "$docs" } }
])

注意事项

  • 无论哪种方案,必须先执行排序,MongoDB集合本身没有固定的存储顺序,不排序的话生成的行号是随机的,筛选结果也无意义。
  • 方案二在集合数据量很大时,$group会把所有文档加载到内存,可能引发性能问题,优先推荐方案一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:00:08