Eliminazione in MongoDB
Come eliminare documenti da MongoDB in Python con PyMongo: delete_one() e delete_many(), filtri, gestione degli errori e pratiche sicure.
PyMongo mette a disposizione due metodi per rimuovere documenti da una collection: delete_one() rimuove il primo documento corrispondente, mentre delete_many() rimuove tutti i documenti corrispondenti. Entrambe sono operazioni precise, basate su filtri — si specifica esattamente quali documenti selezionare usando la stessa sintassi di query di find().
Questo capitolo tratta:
delete_one()— rimuovere un singolo documentodelete_many()— rimuovere più documenti (inclusi tutti i documenti)- Lettura dell'oggetto
DeleteResult - Operatori di filtro che rendono le eliminazioni precise
- Gestione degli errori e pratiche di sicurezza
- Quando eliminare documenti rispetto a eliminare l'intera collection
Prerequisiti: Python 3.8+, PyMongo installato (
pip install pymongo) e un server MongoDB in esecuzione. Consulta MongoDB Get Started per la configurazione e MongoDB Insert per capire come i documenti vengono inseriti in una collection.
Connessione e selezione di una collection
Ogni operazione di eliminazione richiede un MongoClient, un database e una collection:
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["mydatabase"]
col = db["customers"]Tutti gli esempi seguenti presuppongono che col sia definito in questo modo.
Eliminare un documento con delete_one()
delete_one(filter) trova il primo documento che corrisponde al filtro e lo elimina. Se corrispondono più documenti, ne viene rimosso solo uno (l'ordine naturale di MongoDB determina quale).
result = col.delete_one({"name": "Alice"})
print(result.deleted_count) # 1 if a match was found, 0 if notdelete_one() non genera mai un errore quando nessun documento corrisponde — restituisce un DeleteResult con deleted_count = 0.
Corrispondenza su un valore di campo specifico
# 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.")Corrispondenza su un campo annidato
Usa la notazione punto per selezionare campi all'interno di documenti incorporati:
# Delete the first customer whose city is "London"
result = col.delete_one({"address.city": "London"})
print(result.deleted_count) # 1 or 0Eliminare più documenti con delete_many()
delete_many(filter) rimuove ogni documento che corrisponde al filtro. Usalo quando è necessario eliminare un insieme di record con una sola chiamata.
# Delete all customers whose address starts with "S"
result = col.delete_many({"address": {"$regex": "^S"}})
print(result.deleted_count, "documents deleted")Eliminare tutti i documenti in una collection
Passa un filtro vuoto {} per rimuovere tutti i documenti. La collection stessa e i suoi indici rimangono — vengono rimossi solo i documenti:
result = col.delete_many({})
print(result.deleted_count, "documents deleted")Attenzione:
delete_many({})su una collection di produzione è irreversibile. Controlla sempre il filtro ed esegui un backup prima di avviare eliminazioni massive. Se desideri rimuovere completamente la collection (documenti e indici), usacol.drop()— consulta MongoDB Drop Collection.
L'oggetto DeleteResult
Entrambi i metodi restituiscono un DeleteResult. Le due proprietà più utilizzate sono:
| Proprietà | Tipo | Descrizione |
|---|---|---|
deleted_count | int | Numero di documenti effettivamente eliminati |
acknowledged | bool | True se il server ha confermato la scrittura; False per scritture non riconosciute |
result = col.delete_many({"status": "inactive"})
print(f"Deleted: {result.deleted_count}")
print(f"Acknowledged: {result.acknowledged}")Operatori di filtro per eliminazioni precise
Gli stessi operatori di query usati in find() funzionano all'interno dei filtri di eliminazione.
Eliminazione per confronto
# 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}})Eliminazione tramite espressione regolare
# Delete all customers whose name starts with "A" (case-sensitive)
col.delete_many({"name": {"$regex": "^A"}})Eliminazione per esistenza di un campo
# Delete all documents that have no "email" field
col.delete_many({"email": {"$exists": False}})Eliminazione per valore in una lista
# Delete all documents whose status is either "cancelled" or "expired"
col.delete_many({"status": {"$in": ["cancelled", "expired"]}})Gestione degli errori
Racchiudi le operazioni di eliminazione in un blocco try/except per gestire le due modalità di errore più comuni:
pymongo.errors.OperationFailure— il server ha rifiutato l'operazione (ad esempio, l'utente connesso non dispone dei privilegiremovesulla collection).pymongo.errors.ConnectionFailure— la connessione di rete a MongoDB è stata persa.
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}")Esempio pratico: flusso completo
Questo esempio inizializza una collection, esegue eliminazioni mirate e verifica il risultato:
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}]Output atteso:
Inserted: 4
delete_one: 1
delete_many (city ^S): 2
Remaining: [{'name': 'Alice', 'city': 'Oslo', 'active': True}]Eliminare documenti vs. eliminare una collection
Queste due operazioni vengono spesso confuse:
| Operazione | Documenti rimossi | Collection rimossa | Indici rimossi | Velocità |
|---|---|---|---|---|
col.delete_many({}) | Tutti | No | No | Più lenta su grandi insiemi |
col.drop() | Tutti | Sì | Sì | Molto rapida |
Scegli delete_many({}) quando devi svuotare una collection ma mantenere i suoi indici e i validatori dello schema. Scegli col.drop() quando vuoi ripartire da zero — ad esempio, tra le esecuzioni di test o durante una migrazione dello schema. Consulta MongoDB Drop Collection per i dettagli su drop().
Riepilogo
delete_one(filter)rimuove il primo documento corrispondente;delete_many(filter)rimuove tutti i documenti corrispondenti.- Entrambi restituiscono un
DeleteResult— controlladeleted_countper confermare cosa è stato rimosso. - Un filtro vuoto
{}indelete_many()rimuove tutti i documenti dalla collection. - Usa gli operatori di query MongoDB (
$regex,$lt,$in,$exists, …) per costruire filtri precisi. - Racchiudi le operazioni in
try/exceptper gestireOperationFailureeConnectionFailure. - Per rimuovere la collection stessa, usa
col.drop()al suo posto.
Capitoli correlati:
- MongoDB Insert — inserimento di documenti con
insert_one()einsert_many() - MongoDB Update — modifica di documenti esistenti con
update_one()eupdate_many() - MongoDB Drop Collection — rimozione di un'intera collection inclusi i suoi indici
- MongoDB Query — costruzione di filtri con operatori di query
- MongoDB Get Started — installazione di PyMongo e connessione a MongoDB