14

Вопрос по mongodb – Как эффективно удалять документы по запросу в монго?

У меня есть запрос, который выбирает документы для удаления. Прямо сейчас я удаляю их вручную, вот так (используя python):

for id in mycoll.find(query, fields={}):
  mycoll.remove(id)

Это не кажется очень эффективным. Есть ли способ лучше?

EDIT

ОК, я должен извиниться за то, что забыл упомянуть детали запроса, потому что это важно. Вот полный код 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 по значению ключа,leaving only the newest records, Это работает так:

  1. MR the data to (key, count) pairs.
  2. Iterate over all the pairs with count > max_group_size
  3. Query the data by key, while sorting it ascending by the timestamp (the oldest first) and limiting the result to the count - max_group_size oldest records
  4. Delete each and every found record.

Как видите, это решает задачу сокращения дубликатов до не более чем N новейших записей. Итак, последние два шагаforeach-found-remove и это важная деталь моего вопроса, которая меняет все, и я должен был быть более конкретным в этом - извините.

Теперь про команду удаления коллекции. Он принимает запрос, но мой включает сортировку и ограничение. Могу ли я сделать это с помощью remove? Ну, я попробовал:

mydb.static.find(key, limit = group_size - max_group_size, sort=[('test_date', ASCENDING)])

Эта попытка с треском проваливается. Более того, похоже на винт Монго. Обратите внимание:

C:\dev\poc\SDR>python FilterOoklaData.py
bad offset:0 accessing file: /data/db/ookla.0 - consider repairing database

Само собой разумеется, что подход foreach-found-remove работает и дает ожидаемые результаты.

Теперь я надеюсь, что предоставил достаточно контекста и (надеюсь) восстановил мою утраченную честь.

  • Error: User Rate Limit Exceeded$inError: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от mark
  • Let's say, you have 100k documents to delete from a collection. It is better to execute 100 queries that delete 1k documents each than 1 query that deletes all 100k documents.Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от mark
  • 9

    Вы можете удалить его напрямую, используя язык сценариев MongoDB:

    db.mycoll.remove({_id:'your_id_here'});
    

  • 1

    Запустите этот запрос в

    cmd

    db.users.remove( {"_id": ObjectId("5a5f1c472ce1070e11fde4af")});

    Если вы используете node.js, напишите этот код

    User.remove({ _id: req.body.id },, function(err){...});
    

  • 33

    Вы можете использовать запрос

    чтобы удалить все соответствующие документы

    var query = {name: 'John'};
    db.collection.remove(query);
    

    Однако будьте осторожны, если количество соответствующих документов велико, ваша база данных может стать менее отзывчивой. Часто рекомендуется удалять документы небольшими порциями.

    Допустим, у вас есть 100 тыс. Документов для удаления из коллекции. Лучше выполнить 100 запросов, которые удаляют 1 тыс. Документов каждый, чем 1 запрос, удаляющий все 100 тыс. Документов.

  • 2

    Было бы

    deleteMany() быть более эффективным? Я недавно обнаружил, чтоremove() довольно медленно для 6-метровых документов в 100-метровой коллекции документов. Документация на (https://docs.mongodb.com/manual/reference/method/db.collection.deleteMany)

    db.collection.deleteMany(
       <filter>,
       {
          writeConcern: <document>,
          collation: <document>
       }
    )