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

MongoDB按startDate保留重复Hash最旧文档的查询问题

解决MongoDB同Hash去重并保留最早startDate记录的问题

问题背景

需求:对集合中Hash字段重复(数量>1)的文档去重,仅保留startDate最早的记录。

原查询的问题在于:

  • 使用$addToSet收集_id,集合是无序结构,导致dups数组顺序随机;
  • $sort阶段放在$group之后,此时分组结果中无startDate字段,排序完全无效,无法保证保留最早记录。

修正后的查询代码

db.Mydb.aggregate([
  // 先按Hash分组,再按startDate升序排序,确保同Hash下最早的记录排在首位
  { "$sort": { "Hash": 1, "startDate": 1 } },
  {
    "$group": {
      "_id": "$Hash",
      "keepId": { "$first": "$_id" }, // 保留startDate最早的文档ID
      "allIds": { "$push": "$_id" },  // 收集当前Hash下所有文档ID
      "count": { "$sum": 1 }
    }
  },
  // 仅处理存在重复的分组
  { "$match": { "count": { "$gt": 1 } } },
  // 筛选出需要删除的ID(排除要保留的ID)
  {
    "$project": {
      "deleteIds": {
        "$filter": {
          "input": "$allIds",
          "cond": { "$ne": ["$$this", "$keepId"] }
        }
      }
    }
  }
]).forEach(function(doc) {
  if (doc.deleteIds.length > 0) {
    db.Mydb.deleteMany({ "_id": { "$in": doc.deleteIds } });
  }
})

关键逻辑说明

  • 排序前置:在分组前先按Hash和startDate升序排序,确保同Hash分组内,最早的记录处于序列头部;
  • 精准保留:通过$first获取分组头部的_id,即为需要保留的最早记录ID;
  • 批量删除:用$filter排除保留ID,得到所有需要删除的ID列表,批量执行删除操作。

这样就能确保每个重复Hash分组中,仅保留startDate最早的文档,其余重复项被准确删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:30:42