2024-10-14 11:10:43
众所周知,我们常常会用MongoDB存储大量数据。然而,有时候我们忘记在建立集合的时候给某些字段设置unique属性,导致数据库中会存在大量重复的数据,这时候如何删除这些数据就成了一个令人脑壳疼的问题。在数据量较小的情况下,可以直接写一个python脚本,通过导出已有数据并插入到已建立unique索引的集合中解决问题。但是,but,如果数据量较大的话,使用脚本来解决要耗费非常大量的时间,这种时候就需要想想其他办法了
几种方法方法一:使用python脚本处理frompymongoimportMongoClient#打开集合client=MongoClient(address,port)db=client.db_namecollection=db.collection_namepatents=[]#存储已遍历过的unique字段count=0foritemincollection.find():ifitem['key_is_unique']notinpatents:#判断当前文档是否在之前已经遍历过patents.append(item['key_is_unique'])#该文档设置成已遍历else:collection.delete_one(item)#删除重复文档方法二:在mongo命令行使用命令直接处理db.Collection.aggregate([{$group:{_id:{content:'$content',endTime:'$endTime',startTime:'$startTime'},count:{$sum:1},dups:{$addToSet:'$_id'}}},{$match:{count:{$gt:1}}}]).forEach(function(it){it.dups.shift();db.Collection.remove({_id:{$in:it.dups}});});对命令的一些说明
使用aggregate聚合查询重复数据
\$group中是查询条件,根据content、endTime、startTime字段来聚合相同的数据;
\$count用来统计重复出现的次数,\$match来过滤没有重复的数据;
\$addToSet将聚合的数据id放入到dups数组中方便后面使用;
查询结果使用forEach进行迭代id来删除数据
shift()作用是剔除队列中第一条id,避免删掉所有的数据;
方法三:直接在原集合建立索引,在让MongoDB在建立索引的过程中删除重复数据db.Collection.ensureIndex({your_unique_key:1},{unique:true,dropDups:true})
上述命令的dropDups参数告诉MongoDB,如果遇上了unique冲突的数据,就直接删除冲突的数据
方法四:通过MongoDB的原生支持,先导出数据为bson文件,再将bson文件数据导入到已建立索引的新集合中mongodump-ddb_name-ccollection_name-o/tmpdb.new_collection_name.ensureIndex({要建立的索引},{unique:true,dropDups:true})mongorestore-ddb_name-cnew_collection_name/tmp/db_name/collection_name.bson结语上述提供了四种删除MongoDB重复数据的方法,每种方法各有自己的优缺点,大家可以根据自己的需要进行选择。