python进行mongodb-gridfs去重

时间:2021-10-03 03:00:31

说明

由于最开始抓取数据时,出于疏忽,将图片数据存入mongodb时查询图片是否已存在这部分代码出错,导致mongodb中存在大量重复的图片,因此需要对数据库进行去重操作。
而我采用了mongodb提供的GridFS功能来管理图片,与一般的文档去重有所区别,因此经过尝试和摸索后,得到如下解决方案,效率较低,但能有效解决问题。

代码

#-*-coding:utf-8-*-
from pymongo import MongoClient
import json
from gridfs import *
from datetime import datetime

def delete_repeat_data(ip):
beginTime = datetime.now()
print beginTime
client = MongoClient(ip, 27017)
oldDB = client.olddb
oldFS = GridFS(oldDB, collection="images")
collection = oldDB.images.files

newDB = client.newdb
newFS = GridFS(newDB, collection="images")
num = 0
for photo_id in collection.distinct('photo_id'):# 使用distinct方法,获取每一个独特的元素列表,不能直接对fs进行类似操作,会报错
flag = True
for dic in oldFS.find({"photo_id":photo_id}): # 此处字段根据需求设置。fs.find返回值为GridOutCursor,需要遍历获取其中数据,由于同一id对应的数据相同,因此设置flag进行标记,只保存一条记录即可。
if not flag:
break
# 得到图片属性数据
photoDic = {"photo_title":dic.photo_title, "owner_id":dic.owner_id, "owner_name":dic.owner_name, "photo_id":photo_id, "width":dic.width,
"longitude":dic.longitude, "latitude":dic.latitude, "tags":dic.tags, "dateupload":dic.dateupload, "photo_url":dic.photo_url,
"height":dic.height, "datetaken":dic.datetaken}
if newFS.find_one({"photo_id":photo_id}): # 如果此图片在新数据库中已存在,则不保存。一般来说,不需要这段代码,有点多此一举
break
newFS.put(dic.read(), **photoDic) # 将图片数据存入新数据库中
#print photo_id
num += 1
flag =False
if num%1000==0:
print num, datetime.now(), datetime.now()-beginTime

if __name__ == '__main__':
delete_repeat_data('localhost')

欢迎留言交流,以上。