专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

MongoDB 去重

MongoDB 中由于一些误操作或者写入数据的问题可能会产生重复数据,下面以 testCollection 为例进行去重

testCollection 中使用 rid 作为唯一标识,所以这里根据 rid 对数据进行去重,同一个 rid 只保留一项

1、 方案一:将重复数据的 ObjectId 根据 rid 分组,每个分组中只保留一条,其余的数据都使用 ObjectId 删除

这里使用 aggregation 将所有的 doc 根据 rid 聚合,保存在 dups 参数,这样 aggregation 的结果的每一项都是同一个 rid 聚合的结果,每一项都有一个 dups 参数,表示这个 rid 对应的所有 doc 的 ObjectId

然后遍历 aggregation 的结果,对于同一个 rid 只保留 dups 中的第一个 ObjectId,其他的 ObjectId 都加入到 duplicates 数组中

最后将 duplicates 中 ObjectId 对应的所有 doc 依次删掉

var duplicates = [];  // 用于存放需要删除的 doc 的 ObjectId 的数组

db.getCollection("testCollection").aggregate([
  { $match: { 
    title: { "$eq": 'placeholder' }  // 匹配“placeholder”对应的评论
  }},
  { $group: { 
    _id: { rid : "$rid "}, // 根据 rid 进行聚合,聚合结果的每一项都是同一个 rid
    dups: { "$addToSet": "$_id" },  // 将同一个 rid 对应的所有 ObjectId 加入 dups 中
    count: { "$sum": 1 }  // 记录每一个 rid 对应的 ObjectId 的数量
  }}, 
  { $match: { 
    count: { "$gt": 1 }    // 通过前面的 count 将有重复评论的 group 结果筛选出,没有重复的评论不会出现在后面遍历的过程中
  }}
],
{allowDiskUse: true}       // 允许使用写临时文件来加速 aggregation 操作
)
.forEach(function(doc) {
    doc.dups.shift();      // 对每一个 rid 保留第一个 ObjectId
    doc.dups.forEach( function(dupId){ 
        duplicates.push(dupId);   // 将剩下的 ObjectId 都加入待删除 doc 的 ObjectId 数组
        }
    )    
})

db.getCollection("testCollection").remove({_id:{$in:duplicates}})  // 将 duplicates 中 ObjectId 对应的 doc 删除

结果报错:

Document 0 is too large for the cluster. Document is 68310755 bytes, max is 16777216.

原因是这里重复数据过多,导致生成的 duplicates 太大,而 MongoDB 对于 BSON 文件大小的限制是 16MB

The maximum BSON document size is 16 megabytes. The maximum document size helps ensure that a single document cannot use excessive amount of RAM or, during transmission, excessive amount of bandwidth. To store documents larger than the maximum size, MongoDB provides the GridFS API. See mongofiles and the documentation for your driver for more information about GridFS.

1、 方案2:不再将 aggregation 操作结果的 ObjectId 保存到 duplicates 中,而是直接遍历,依次删除多余的 ObjectId 对应的 doc

db.getCollection("testCollection").aggregate([
  { $match: { 
    title: { "$eq": 'placeholder' }
  }},
  { $group: { 
    _id: { rid: "$rid"},
    dups: { "$addToSet": "$_id" }, 
    count: { "$sum": 1 } 
  }}, 
  { $match: { 
    count: { "$gt": 1 }
  }}
],
{allowDiskUse: true}
)
.forEach(function(doc) {
    doc.dups.shift();
    db.getCollection("testCollection").remove({_id : {$in: doc.dups }});
})

参考:

文章永久链接:https://tech.souyunku.com/45708

未经允许不得转载:搜云库技术团队 » MongoDB 去重

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们