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

MongoDB如何查询指定用户最近n个月数据且每月仅返回最后一条记录

MongoDB按用户查询近n个月每月最新记录解决方案

需求说明

查询指定用户最近n个月的数据,同一个月存在多条记录时仅返回当月最后一条存入的记录,最终结果按月份升序排列。
示例:n为3、userId为userId1时返回该用户最近3个月每个月的最新一条记录。

现有写法问题

你当前使用的普通find+limit逻辑只能返回最新的n条全量记录,若同一个月存在多条数据会返回多条同月结果,无法满足按月份去重的要求。

适配mongojs v4.1.2的实现代码

const queryMonthCount = 3; // 自定义查询的最近月份数
const targetUserId = 'userId1'; // 自定义目标用户ID

db.collection(collection_name)
  .aggregate([
    // 1. 前置筛选目标用户的所有记录,缩小后续计算范围
    { $match: { userId: targetUserId } },
    // 2. 统一将时间转为ISODate类型(如果你的processedAt已经是ISODate可省略此步)
    { $set: { processedAt: { $toDate: "$processedAt" } } },
    // 3. 按时间倒序排列,保证同一个月的记录中最新的排在最前
    { $sort: { processedAt: -1 } },
    // 4. 按年月分组,每组取第一条即当月最新记录
    {
      $group: {
        _id: { $dateToString: { format: "%Y-%m", date: "$processedAt" } },
        latestDoc: { $first: "$$ROOT" }
      }
    },
    // 5. 按年月倒序取最近的n个月数据
    { $sort: { _id: -1 } },
    { $limit: queryMonthCount },
    // 6. 还原记录结构,去掉分组的包裹层
    { $replaceRoot: { newRoot: "$latestDoc" } },
    // 7. 最终按月份升序排列,符合返回要求
    { $sort: { processedAt: 1 } },
    // 可选:如果不需要返回_id可开启下方投影
    // { $project: { _id: 0 } }
  ])
  .toArray()

逻辑说明

  • 前置$match筛选可以大幅降低后续计算的数据量,提升查询性能
  • 按时间倒序后分组取第一条的逻辑,避免了复杂的最大值匹配,兼容绝大多数MongoDB版本
  • 两次排序分别满足「取最近n个月」和「最终结果按月升序返回」的要求

样例验证

样例输入

[
 {
   "_id": "objectId(\"aaaaaa\")",
   "userId": "userId1",
   "processedAt": "2021-06-01T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"bbbbb\")",
   "userId": "userId1",
   "processedAt": "2021-10-11T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"ccccc\")",
   "userId": "userId1",
   "processedAt": "2021-10-25T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"eeeee\")",
   "userId": "userId1",
   "processedAt": "2021-09-12T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"fffff\")",
   "userId": "userId1",
   "processedAt": "2021-09-28T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"ggggg\")",
   "userId": "userId1",
   "processedAt": "2021-09-23T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"hhhhh\")",
   "userId": "userId1",
   "processedAt": "2021-07-23T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"iiiii\")",
   "userId": "userId2",
   "processedAt": "2021-09-29T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"jjjjj\")",
   "userId": "userId1",
   "processedAt": "2022-01-29T12:16:49.349Z"
 },
 {
   "_id": "objectId(\"kkkkk\")",
   "userId": "userId1",
   "processedAt": "2022-02-29T12:16:49.349Z"
 }
]

样例输出

[
  {
    "_id": "objectId(\"ccccc\")",
    "userId": "userId1",
    "processedAt": "2021-10-25T12:16:49.349Z"
  },
  {
    "_id": "objectId(\"jjjjj\")",
    "userId": "userId1",
    "processedAt": "2022-01-29T12:16:49.349Z"
  },
  {
    "_id": "objectId(\"kkkkk\")",
    "userId": "userId1",
    "processedAt": "2022-02-29T12:16:49.349Z"
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:06:05