mongodb去重

由于某些原因,我们的MongoDB里存在重复数据,甚至已经影响到数据统计。

其实在MongoDB 3.2之前可以通过索引直接去重。但这一特性在3.2版本之初已经移除。

{unique : true, dropDups : true}   # 无法使用了

大概思路是,通过aggregationgroup出重复的键值对并做count,之后match所有count>2的键值对,认为他们是重复的,保留其中一条,删除其余。实现代码如下:

from pymongo import DeleteOne
from threading import Thread
from apscheduler.schedulers.blocking import BlockingScheduler
from Application.Utils.Log import Log

class DupKeywordRemove:
    def __init__(self):
        models = [monde1, monde2, monde2,
                  monde3, monde4, monde4]  # mongoengine的modle
        self.pipeline = [
            # 根据几个字段去判断键值对的唯一性,这里特别写明了{"$exists": True},必须保证需要判断的字段完成,否则会影响到后面的group
            {"$match": {
                "keyword": {"$exists": True},
                "country_id": {"$exists": True},
            }},
            # 将重复的键值对group起来,并用count计数
            {"$group": {
                "_id": {
                    "keyword": "$keyword",
                    "country_id": "$country_id",
                },
                "count": {"$sum": 1}
            }},
            # 匹配count大于2的键值对,他们就是重复的
            {"$match": {
                "count": {"$gt": 1}
            }}
        ]
        self.main(models)

    def find_dup_id(self, model):
        try:
            _collection = model._get_collection()
            # 配置allowDiskUse=True应对mongodb的16M limit
            all_dup_key = list(_collection.aggregate(self.pipeline, allowDiskUse=True))
            delete_list = []
            # 重复的doc作为list返回,每一组键值对作为find条件去数据库里查询
            for dup_event in all_dup_key:
                match_pipe = dup_event[‘_id‘]
                remove_id_list = []
                dups = list(_collection.find(match_pipe))
                if len(dups) >= 2:
                    for key in dups:
                        remove_id_list.append(key[‘_id‘])
                    needToSave = remove_id_list.pop()  # pop一个出去,作为保留的doc
                    for to_del in remove_id_list:
                        delete_list.append(
                            DeleteOne({
                                ‘_id‘: to_del
                            })
                        )
            print(_collection, len(delete_list))
            if delete_list:
                print(‘删除重复数据‘)
                _collection.bulk_write(delete_list)
            else:
                print(‘无重复数据‘)
                pass
        except Exception as e:
            Log(‘keyword_dup_remove‘).info(e)

    def main(self, models):
        t_li = []
        for _model in models:
            t_li.append(
                Thread(
                    target=self.find_dup_id,
                    kwargs={
                        ‘model‘: _model,
                    }
                )
            )
        for t in t_li:
            t.start()
        for t in t_li:
            t.join()

if __name__ == ‘__main__‘:
    DupKeywordRemove()

参考链接:http://yangcongchufang.com/remove-duplicate-from-mongodb.html

原文地址:https://www.cnblogs.com/clbao/p/11220851.html

时间: 2024-08-08 08:28:12

mongodb去重的相关文章

MongoDB 权限、备份、还原、去重

MongoDB 权限.备份.还原.去重 权限 数据安全是数据库至关重要的一部分,那么下面是设置MongoDB的用户权限的大致过程. 首先,在无授权模式下新建数据库管理员: 启动数据库服务: mongod 启用命名行工具: mongo use admin db.createUser({user:"gly",pwd:"[email protected]",roles:[{role:"userAdminAnyDatabase",db:"adm

mongodb中处理插入数据去重问题

最近在写一个爬虫工具,将网站的数据储存到mongodb中,由于数据有重复的,所以我就在建立数据库的时候,为集合建立了索引,下面说下我的步骤,集合名称为drugitem, 下面是集合截图: 我要为name字段创建唯一索引,因为要保证name没有重复: 就这样我运行程序发现数据比原来没有设置唯一索引时少了好多,我仔细查看发现程序在name字段重复的地方停止了,这不是我想要的结果,因为后面的数据还没有查询完成.于是我就删除了原来创建的name索引: 然后remove数据,重新按照老办法重新抓取数据,这

如何在Mongodb集合中统计去重之后的数据

比方说我们有个Mongodb集合, 以这个简单的集合为例,我们需要集合中包含多少不同的手机号码,首先想到的应该就是使用distinct关键字, db.tokencaller.distinct('Caller').length 如果想查看具体的而不同的手机号码,那么可以省略后面的length属性,因为db.tokencaller.distinct('Caller')返回的是由所有去重手机号码组成的数组. 但是,这种方式对于所有情况都是满足的嘛?并不如此,如果要统计的集合记录数较大,如千万级别的,那

Mongodb去除重复的数据,pymongo去重

接上一篇的,发现爬斗鱼主播信息存入Mongodb数据库后,发现很多重复的数据,毕竟斗鱼不可能有这么多的主播,所以很多页是有重复的主播房间的. 查了一下怎么去重,发现比较麻烦,与其存入重复的数据后面再去重,还不如在存入数据库的时候就检查,不去存入重复的数据,这样就避免了后期再去做去重工作.于是改动如下: #-*- coding:utf-8 -*- #_author:John #date:2018/10/25 0:07 #softwave: PyCharm import requests impor

去重mongodb LIST

using MongoDB; using DockSample.DB; using MongoDB.Driver; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Window

mongodb distinct去重

MongoDB的destinct命令是获取特定字段中不同值列表.该命令适用于普通字段,数组字段和数组内嵌文档. mongodb的distinct的语句: db.users.distinct('last_name') 等同于 SQL 语句: select DISTINCT last_name from users 表示的是根据指定的字段返回不同的记录集. 一个简单的实例: // > db.addresses.insert({"zip-code": 10010}) > db.a

mongodb讲解

mongodb 1标题1错误!未定义书签. 1.1标题2错误!未定义书签. 1.1.1标题3错误!未定义书签.   1 概述 mongodb:是介于关系型与非关系之间的一种数据库系统! 1.1 概述,mongodb是文档型非关系数据库 是一种数据库,类似MySQL. 不同于MySQL的是:是一种"非关系型数据库". 非关系型数据库:NOSQL-(Not Only SQL, non-relation).不以关系型(二维表)进行数据存储结构的数据库的统称.包括:memcached(内存型数

MongoDB使用小结:一些常用操作分享

本文整理了一年多以来我常用的MongoDB操作,涉及mongo-shell.pymongo,既有运维层面也有应用层面,内容有浅有深,这也就是我从零到熟练的历程. MongoDB的使用之前也分享过一篇,稍微高阶点:见这里:<MongoDB使用小结> 1.shell登陆和显示 假设在本机上有一个端口为17380的MongoDB服务,假设已经把mongo bin文件加入到系统PATH下. 登陆:mongo --port 17380 显示DB:show dbs 进入某DB:use test_cswuy

Mongodb基础用法及查询操作[转载]

插入多条测试数据> for(i=1;i<=1000;i++){... db.blog.insert({"title":i,"content":"mongodb测试文章.","name":"刘"+i});                                                      ... } db.blog.list.find().limit(10).forEach(