W3docs

Удаление в MongoDB

Как удалять документы из MongoDB в Python с помощью delete_one() и delete_many() PyMongo: фильтры, обработка ошибок и безопасные шаблоны.

PyMongo предоставляет два метода для удаления документов из коллекции: delete_one() удаляет первый подходящий документ, а delete_many() удаляет все совпадающие документы. Оба метода работают с фильтрами — вы точно указываете, какие документы нужно удалить, используя тот же синтаксис запросов, что и в find().

В этой главе рассматривается:

  • delete_one() — удаление одного документа
  • delete_many() — удаление нескольких документов (в том числе всех)
  • Чтение объекта DeleteResult
  • Операторы фильтров для точного удаления
  • Обработка ошибок и безопасные практики
  • Когда удалять документы, а когда удалять всю коллекцию

Предварительные требования: Python 3.8+, установленный PyMongo (pip install pymongo) и работающий сервер MongoDB. Инструкции по настройке см. в разделе MongoDB Get Started, а о том, как документы попадают в коллекцию, — в разделе MongoDB Insert.

Подключение и выбор коллекции

Для любой операции удаления необходимы MongoClient, база данных и коллекция:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["mydatabase"]
col = db["customers"]

Во всех примерах ниже предполагается, что col определён именно так.

Удаление одного документа с помощью delete_one()

delete_one(filter) находит первый документ, соответствующий фильтру, и удаляет его. Если фильтру соответствует несколько документов, удаляется только один (MongoDB определяет его по естественному порядку).

result = col.delete_one({"name": "Alice"})
print(result.deleted_count)  # 1 if a match was found, 0 if not

delete_one() не вызывает ошибку, если подходящий документ не найден — метод возвращает DeleteResult со значением deleted_count = 0.

Поиск по конкретному значению поля

# Delete the customer whose name is "Bob"
result = col.delete_one({"name": "Bob"})

if result.deleted_count == 1:
    print("Document deleted.")
else:
    print("No matching document found.")

Поиск по вложенному полю

Для обращения к полям во вложенных документах используйте точечную нотацию:

# Delete the first customer whose city is "London"
result = col.delete_one({"address.city": "London"})
print(result.deleted_count)  # 1 or 0

Удаление нескольких документов с помощью delete_many()

delete_many(filter) удаляет все документы, соответствующие фильтру. Используйте его, когда нужно очистить набор записей за один вызов.

# Delete all customers whose address starts with "S"
result = col.delete_many({"address": {"$regex": "^S"}})
print(result.deleted_count, "documents deleted")

Удаление всех документов в коллекции

Передайте пустой фильтр {}, чтобы удалить все документы. Сама коллекция и её индексы при этом сохраняются — исчезают только документы:

result = col.delete_many({})
print(result.deleted_count, "documents deleted")

Предупреждение: delete_many({}) на рабочей коллекции необратимо. Всегда тщательно проверяйте фильтр и делайте резервную копию перед массовым удалением. Если нужно удалить коллекцию целиком (документы и индексы), используйте col.drop() — подробнее в разделе MongoDB Drop Collection.

Объект DeleteResult

Оба метода возвращают объект DeleteResult. Чаще всего вам потребуются два его свойства:

СвойствоТипОписание
deleted_countintКоличество фактически удалённых документов
acknowledgedboolTrue, если сервер подтвердил запись; False для неподтверждённых записей
result = col.delete_many({"status": "inactive"})
print(f"Deleted: {result.deleted_count}")
print(f"Acknowledged: {result.acknowledged}")

Операторы фильтров для точного удаления

Те же операторы запросов, что используются в find(), работают и в фильтрах удаления.

Удаление по условию сравнения

# Delete all orders with a quantity less than 10
col.delete_many({"qty": {"$lt": 10}})

# Delete all orders with a quantity greater than or equal to 100
col.delete_many({"qty": {"$gte": 100}})

Удаление по регулярному выражению

# Delete all customers whose name starts with "A" (case-sensitive)
col.delete_many({"name": {"$regex": "^A"}})

Удаление по наличию поля

# Delete all documents that have no "email" field
col.delete_many({"email": {"$exists": False}})

Удаление по значению из списка

# Delete all documents whose status is either "cancelled" or "expired"
col.delete_many({"status": {"$in": ["cancelled", "expired"]}})

Обработка ошибок

Оборачивайте операции удаления в блок try/except, чтобы обрабатывать два наиболее распространённых типа ошибок:

  • pymongo.errors.OperationFailure — сервер отклонил операцию (например, у подключённого пользователя нет прав remove на коллекцию).
  • pymongo.errors.ConnectionFailure — соединение с MongoDB было разорвано.
import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
col = client["mydatabase"]["customers"]

try:
    result = col.delete_many({"status": "inactive"})
    print(f"{result.deleted_count} documents deleted.")
except pymongo.errors.OperationFailure as e:
    print(f"Server error: {e}")
except pymongo.errors.ConnectionFailure as e:
    print(f"Connection error: {e}")

Практический пример: полный рабочий процесс

Этот пример наполняет коллекцию данными, выполняет точечные удаления и проверяет результат:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
col = client["mydatabase"]["customers"]

# 1. Start clean
col.drop()

# 2. Insert sample documents
col.insert_many([
    {"name": "Alice", "city": "Oslo",   "active": True},
    {"name": "Bob",   "city": "Sydney", "active": False},
    {"name": "Carol", "city": "Seattle","active": False},
    {"name": "Dave",  "city": "Sofia",  "active": True},
])
print("Inserted:", col.count_documents({}))  # 4

# 3. Delete the one inactive customer named "Bob"
r1 = col.delete_one({"name": "Bob", "active": False})
print("delete_one:", r1.deleted_count)  # 1

# 4. Delete all customers in cities that start with "S"
r2 = col.delete_many({"city": {"$regex": "^S"}})
print("delete_many (city ^S):", r2.deleted_count)  # 2 (Carol/Seattle, Dave/Sofia)

# 5. Check what remains
remaining = list(col.find({}, {"_id": 0}))
print("Remaining:", remaining)  # [{'name': 'Alice', 'city': 'Oslo', 'active': True}]

Ожидаемый вывод:

Inserted: 4
delete_one: 1
delete_many (city ^S): 2
Remaining: [{'name': 'Alice', 'city': 'Oslo', 'active': True}]

Удаление документов и удаление коллекции

Эти две операции часто путают:

ОперацияДокументы удаленыКоллекция удаленаИндексы удаленыСкорость
col.delete_many({})ВсеНетНетМедленнее на больших наборах
col.drop()ВсеДаДаОчень быстро

Выбирайте delete_many({}), когда нужно очистить коллекцию, но сохранить индексы и валидаторы схемы. Выбирайте col.drop(), когда нужен полностью чистый результат — например, между тестовыми запусками или при миграции схемы. Подробнее о drop() — в разделе MongoDB Drop Collection.

Резюме

  • delete_one(filter) удаляет первый совпадающий документ; delete_many(filter) удаляет все совпадающие документы.
  • Оба метода возвращают DeleteResult — проверяйте deleted_count, чтобы убедиться в результате.
  • Пустой фильтр {} в delete_many() удаляет все документы из коллекции.
  • Используйте операторы запросов MongoDB ($regex, $lt, $in, $exists, …) для построения точных фильтров.
  • Оборачивайте операции в try/except для обработки OperationFailure и ConnectionFailure.
  • Чтобы удалить саму коллекцию, используйте col.drop().

Связанные главы:

  • MongoDB Insert — вставка документов с помощью insert_one() и insert_many()
  • MongoDB Update — изменение существующих документов с помощью update_one() и update_many()
  • MongoDB Drop Collection — удаление коллекции целиком вместе с индексами
  • MongoDB Query — построение фильтров с операторами запросов
  • MongoDB Get Started — установка PyMongo и подключение к MongoDB
Was this page helpful?