У меня есть запрос, который выбирает документы для удаления. Прямо сейчас я удаляю их вручную, как это (используя 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
за каждое значение ключа, оставляя только самые новые записи. Он работает следующим образом:
- MR данные в пары
(key, count)
. - Итерации по всем парам с помощью
count > max_group_size
- Запросить данные
key
, сортируя его по возрастанию по метке времени (самая старая первая) и ограничивая результатcount - max_group_size
самыми старыми записями - Удалить каждую найденную запись.
Как вы можете видеть, это выполняет задачу сокращения дубликатов до максимально N новейших записей. Итак, последние два шага foreach-found-remove
, и это важная деталь моего вопроса, которая меняет все, и я должен был быть более конкретным об этом - извините.
Теперь о команде удаления remove. Он принимает запрос, но мой включает сортировку и ограничение. Могу ли я сделать это с удалением? Ну, я пробовал:
mydb.static.find(key, limit = group_size - max_group_size, sort=[('test_date', ASCENDING)])
Эта попытка терпит неудачу. Кроме того, кажется, винт mongo.Observe:
C:\dev\poc\SDR>python FilterOoklaData.py
bad offset:0 accessing file: /data/db/ookla.0 - consider repairing database
Излишне говорить, что подход foreach-found-remove работает и дает ожидаемые результаты.
Теперь, надеюсь, я предоставил достаточный контекст и (надеюсь) восстановил утраченную честь.