当前位置:  开发笔记 > 编程语言 > 正文

pymongo:删除重复项(map reduce?)

如何解决《pymongo:删除重复项(mapreduce?)》经验,为你挑选了1个好方法。

我有一个包含多个集合的数据库(整体约15mil文档),文档看起来像这样(简化):

{'Text': 'blabla', 'ID': 101}
{'Text': 'Whuppppyyy', 'ID': 102}
{'Text': 'Abrakadabraaa', 'ID': 103}
{'Text': 'olalalaal', 'ID': 104}
{'Text': 'test1234545', 'ID': 104}
{'Text': 'whapwhapwhap', 'ID': 104}

它们都有一个唯一的_id字段,但我想删除与另一个字段(外部ID字段)相对应的重复项.

首先,我尝试了一种非常手动的方法,然后使用列表和删除,但数据库看起来太大,需要很长时间并且不实用.

其次,以下版本不再适用于当前的MongoDB版本,即使有人提出建议.

db.collection.ensureIndex( { ID: 1 }, { unique: true, dropDups: true } )

所以,现在我正在尝试创建一个map reduce解决方案,但我真的不知道我在做什么,特别是在使用另一个字段(不是数据库_id)来查找和删除重复项时遇到困难.这是我糟糕的第一种方法(从一些互联网来源采用):

map = Code("function(){ if(this.fieldName){emit(this.fieldName,1);}}")
reduce = Code("function(key,values) {return Array.sum(values);}")
res = coll.map_reduce(map,reduce,"my_results");

response = []
for doc in res.find():
    if(doc['value'] > 1):
        count = int(doc['value']) - 1
        docs = col.find({"fieldName":doc['ID']},{'ID':1}).limit(count)
        for i in docs:
            response.append(i['ID'])

coll.remove({"ID": {"$in": response}})

任何帮助减少外部ID字段中的任何重复(留下一个条目),将非常了解;)谢谢!



1> chridam..:

另一种方法是使用aggregation framework比map-reduce更好的性能.考虑以下聚合管道,作为聚合管道的第一阶段,$group操作员按ID字段对文档进行分组,并使用运算符在字段中存储分组记录的unique_ids每个_id$addToSet.所述$sum累加器操作者加起来传递给它的字段的值,在这种情况下,常数1 -从而计数的分组的记录的数量进计数字段.另一个管道步骤$match过滤计数至少为2的文档,即重复项.

一旦你从聚集的结果,你迭代光标删除第一个_idunique_ids外地,然后推入其余稍后将用于去除重复(减去一个条目)数组:

cursor = db.coll.aggregate(
    [
        {"$group": {"_id": "$ID", "unique_ids": {"$addToSet": "$_id"}, "count": {"$sum": 1}}},
        {"$match": {"count": { "$gte": 2 }}}
    ]
)

response = []
for doc in cursor:
    del doc["unique_ids"][0]
    for id in doc["unique_ids"]:
        response.append(id)

coll.remove({"_id": {"$in": response}})

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有