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

MongoDB聚合如何限制$match中$in对应每个facilityId仅返回4条最新文件记录

问题原因说明

  1. 直接用全局$limit只能限制总返回条数,无法实现分组限流。
  2. 你之前遇到的Bad projection specification报错,是因为MongoDB投影规则不允许在排除模式(仅指定某个字段设为0不返回)下同时新增/修改计算字段,$slice属于计算字段操作,因此和file:0的排除规则冲突。
  3. 你原代码里$sort: { createdAt: 1 }是按创建时间升序排列,返回的是最早创建的记录,要获取最新创建的需要改为降序-1。

正确聚合查询代码

const files = await File.aggregate([
  // 过滤目标facilityId的所有记录,缩小数据集
  {
    $match: { facilityId: { $in: facilities } }
  },
  // 按创建时间倒序,保证最新记录排在分组的最前面
  {
    $sort: { createdAt: -1 }
  },
  // 按facilityId分组,同组所有文档存入临时数组
  {
    $group: {
      _id: "$facilityId",
      docs: { $push: "$$ROOT" }
    }
  },
  // 截取每个分组前4条,即当前facilityId最新的4条记录
  {
    $project: {
      docs: { $slice: ["$docs", 4] }
    }
  },
  // 拆分临时数组为单条独立文档
  {
    $unwind: "$docs"
  },
  // 将文档内容恢复为根级结构
  {
    $replaceRoot: { newRoot: "$docs" }
  },
  // 排除不需要的file字段
  {
    $project: {
      file: 0
    }
  }
])

性能优化方案

如果你的数据集较大,分组时$push整个文档会占用额外内存,可以在分组阶段就指定需要返回的字段,跳过file字段,省略最后一步的排除投影,性能更好:

const files = await File.aggregate([
  { $match: { facilityId: { $in: facilities } } },
  { $sort: { createdAt: -1 } },
  {
    $group: {
      _id: "$facilityId",
      docs: {
        $push: {
          _id: "$_id",
          name: "$name",
          userId: "$userId",
          facilityId: "$facilityId",
          patientId: "$patientId",
          type: "$type",
          accessed: "$accessed",
          sent: "$sent",
          createdAt: "$createdAt",
          updatedAt: "$updatedAt"
        }
      }
    }
  },
  { $project: { docs: { $slice: ["$docs", 4] } } },
  { $unwind: "$docs" },
  { $replaceRoot: { newRoot: "$docs" } }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:54:03