我有一个查询,用于选择要删除的文档。目前,我是手动删除它们,就像这样(使用python):
for id in mycoll.find(query, fields={}):
mycoll.remove(id)
这似乎不是非常有效率。有更好的方法吗?
编辑
好的,我忘记提及查询细节并因此道歉,因为这很重要。以下是完整的 Python 代码:
def reduce_duplicates(mydb, max_group_size):
# 1. Count the group sizes
res = mydb.static.map_reduce(jstrMeasureGroupMap, jstrMeasureGroupReduce, 'filter_scratch', full_response = True)
# 2. For each entry from the filter scratch collection having count > max_group_size
deleteFindArgs = {'fields': {}, 'sort': [('test_date', ASCENDING)]}
for entry in mydb.filter_scratch.find({'value': {'$gt': max_group_size}}):
key = entry['_id']
group_size = int(entry['value'])
# 2b. query the original collection by the entry key, order it by test_date ascending, limit to the group size minus max_group_size.
for id in mydb.static.find(key, limit = group_size - max_group_size, **deleteFindArgs):
mydb.static.remove(id)
return res['counts']['input']
那么,这个程序是做什么的?它将重复键的数量减少到每个键值最多 max_group_size
个,只保留最新的记录。它的工作原理如下:
- 将数据映射成
(键, 计数)
对。 - 迭代所有满足
计数 > max_group_size
的键值对。 - 按时间戳升序排序(最早的在前面)并限制结果为最旧的前
count - max_group_size
条记录,通过key
查询数据。 - 删除每个找到的记录。
从中可以看到,这实现了将重复项减少到最多 N 条最新记录的任务。所以,最后两步是foreach-found-remove
,这是我问题的重要细节,它改变了一切,我必须更具体地描述它 - 抱歉。
现在,关于集合的删除命令。它确实接受查询,但我的查询包括排序和限制。我能用删除命令实现吗?好吧,我已经试过了:
mydb.static.find(key, limit = group_size - max_group_size, sort=[('test_date', ASCENDING)])
这个尝试惨败了。此外,它似乎会损坏Mongo数据库。观察:
C:\dev\poc\SDR>python FilterOoklaData.py
bad offset:0 accessing file: /data/db/ookla.0 - consider repairing database
毋庸置疑,使用foreach-found-remove方法可以正常工作并产生预期的结果。
现在,我希望我已经提供了足够的上下文,并(希望)恢复了我的失落荣誉。
$in
运算符发送多个删除命令。 - Sergio Tulentsev