Быстрый запрос и удаление документов большой коллекции в MongoDB

#mongodb #mongodb-query #delete-file

#mongodb #mongodb-запрос #удалить-файл

Вопрос:

У меня есть коллекция (скажем, CollOne) с несколькими миллионами документов. Они имеют общее поле «id»

 {...,"id":1}
{...,"id":2}
  

Мне нужно удалить некоторые документы в CollOne по идентификатору. Эти идентификаторы хранятся в документе в другой коллекции (CollTwo). Этот документ ids_to_delete имеет следующую структуру

 {"action_type":"toDelete","ids":[4,8,9,....]}
  

Поскольку CollOne довольно большой, поиск и удаление одного документа займет довольно много времени. Есть ли какой-либо способ ускорить процесс?

Ответ №1:

Например, вы не можете избежать операции удаления в базе данных, если хотите что-либо удалить. Если у вас возникли проблемы с производительностью, я бы просто рекомендовал убедиться, что у вас есть индекс, построенный на id поле, иначе Mongo будет использовать a COLLSCAN для удовлетворения запроса, что означает, что он будет повторять всю colLOne коллекцию, и я думаю, где вы чувствуете боль.

Как только вы убедитесь, что индекс построен, нет «более» эффективного способа, чем использование deleteMany .

 db.collOne.deleteMany({id: {$in: [4, 8, 9, .... ]})
  
  • Если у вас нет индекса и вам интересно, как его создать, вам следует использовать createIndex следующим образом:
    (До версии 4.2 создание индекса блокировало всю базу данных, в больших масштабах это могло занять до нескольких часов, если не больше, чтобы избежать этого, используйте background опцию)
 db.collOne.createIndex({id: 1}) 
  

—- РЕДАКТИРОВАТЬ —-

В оболочке Mongo:

Оболочка Mongo основана на javascript, поэтому вам просто нужно выполнить ту же логику с синтаксисом js, вот как я бы это сделал:

 let toDelete = db.collTwo.findOne({ ... })
db.collOne.deleteMany({id: {$in: toDelete.ids}})
  

введите описание изображения здесь

Комментарии:

1. Спасибо за ваш быстрый ответ! Действительно сэкономил мне много времени. Мне также интересно, есть ли способ заменить [4,8,9, …,] в поле $in некоторой ссылкой на документ ids_to_delete? что-то вроде {$in: CollTwo.find({«action_type»:»toDelete»}).field(«ids»)}. Я использую Python, поэтому я могу запросить две коллекции отдельно и выполнить работу по удалению. Но мне просто интересно, могу ли я просто использовать Mongo-shell для этого. Извините, если этот вопрос очень простой.

2. Да, конечно, есть, вы используете pymongo или собственный пакет mongo?

3. Я использую pymongo. Извините, если я не ясно выразился. Я имею в виду, что я знаю, как использовать pymongo для завершения задачи (например, поместить список в поле $in). Но как это сделать в Mongo-shell? Спасибо!

4. Оболочка Mongo основана на javascript, но «логика», которую вы хотите выполнить, остается прежней, я отредактировал ее в качестве примера того, как выполнить эти два в оболочке.