W3docs

Iniziare con MongoDB

Impara a installare MongoDB, connetterti con PyMongo ed eseguire operazioni CRUD di base in Python con esempi chiari e funzionanti.

Questo capitolo introduce MongoDB e mostra come utilizzarlo da Python tramite il driver PyMongo. Al termine avrai MongoDB installato, una connessione funzionante e una visione chiara di come inserire, interrogare, aggiornare ed eliminare documenti.

Cos'è MongoDB?

MongoDB è un database di documenti — un tipo di database NoSQL che archivia i record come documenti in formato JSON invece di righe e colonne. Ogni documento è un oggetto autocontenuto che può avere campi annidati e array, il che lo rende particolarmente adatto per dati che non si adattano facilmente a uno schema fisso.

Caratteristiche principali:

  • Schema flessibile. Due documenti nella stessa collection possono avere campi completamente diversi.
  • Linguaggio di query ricco. Filtra, proietta, ordina, limita e aggrega con una singola chiamata al driver.
  • Scalabilità orizzontale. Lo sharding integrato e i replica set gestiscono grandi volumi di dati e alta disponibilità.
  • JSON nativo. I documenti sono archiviati come BSON (Binary JSON), quindi i dizionari Python si mappano direttamente ai documenti MongoDB.

Quando scegliere MongoDB rispetto a un database relazionale

SituazioneAdatto?
Struttura dei dati in rapida evoluzione (prototipi, API)
Dati gerarchici / annidati
Query complesse JOIN su più tabellePreferire SQL
Transazioni ACID forti su molte tabellePreferire SQL
Ricerca full-text su larga scalaCombinare con Elasticsearch

Installazione di MongoDB

Opzione 1 — Installazione locale

Scarica il MongoDB Community Server da mongodb.com/try/download/community, scegli il tuo sistema operativo e segui l'installer. Poi avvia il server:

# macOS / Linux
mongod --dbpath /data/db

# Windows (PowerShell, run as Administrator)
mongod --dbpath "C:\data\db"

Verifica che MongoDB sia in esecuzione aprendo un secondo terminale e lanciando:

mongosh --eval "db.adminCommand('ping')"

Output atteso:

{ ok: 1 }

Opzione 2 — Docker (il più rapido per lo sviluppo)

Se hai Docker installato, puoi saltare l'installazione locale:

docker run -d --name mongo -p 27017:27017 mongo:7

Questo scarica l'immagine ufficiale di MongoDB 7 ed espone la porta 27017 sulla tua macchina. Fermalo con docker stop mongo.

Opzione 3 — MongoDB Atlas (cloud)

Atlas è il servizio cloud completamente gestito di MongoDB con un piano gratuito. Dopo la registrazione, copia la stringa di connessione dalla dashboard — ha questo aspetto:

mongodb+srv://username:[email protected]/

Puoi usare quell'URI ovunque vedi mongodb://localhost:27017/ in questo capitolo.

Installazione del driver PyMongo

PyMongo è il driver Python ufficiale per MongoDB. Installalo con pip:

pip install pymongo

Per usare MongoDB Atlas, installa anche i componenti aggiuntivi che includono il resolver DNS:

pip install "pymongo[srv]"

Verifica l'installazione:

import pymongo
print(pymongo.version)
# e.g. 4.7.3

Connessione a MongoDB

MongoClient è il punto di ingresso per tutte le operazioni del driver. Crea un solo client per applicazione e riutilizzalo — il client gestisce internamente un connection pool.

from pymongo import MongoClient

# Local server with default host and port
client = MongoClient("mongodb://localhost:27017/")

# Verify connectivity (raises ConnectionFailure if the server is unreachable)
client.admin.command("ping")
print("Connected successfully")

Per il codice in produzione, gestisci sempre gli errori di connessione in modo esplicito:

from pymongo import MongoClient
from pymongo.errors import ConnectionFailure

client = MongoClient("mongodb://localhost:27017/", serverSelectionTimeoutMS=3000)

try:
    client.admin.command("ping")
    print("Connected to MongoDB")
except ConnectionFailure as e:
    print("Connection failed:", e)

Formato della stringa di connessione

mongodb://[username:password@]host[:port][/database][?options]

Opzioni comuni:

OpzioneEsempioScopo
authSourceauthSource=adminDatabase usato per l'autenticazione
replicaSetreplicaSet=rs0Connessione a un replica set
tls=truetls=trueAbilitazione TLS/SSL
serverSelectionTimeoutMSserverSelectionTimeoutMS=5000Timeout per la selezione del server

Database e Collection

MongoDB organizza i dati in una gerarchia a due livelli:

  • Un database raggruppa collection correlate (simile a uno schema o database SQL).
  • Una collection contiene documenti (simile a una tabella SQL, ma senza schema fisso).

Entrambi vengono creati in modo lazy — vengono generati la prima volta che inserisci un documento. Non è mai necessario eseguire CREATE DATABASE o CREATE TABLE.

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")

# Reference a database (not yet created on disk)
db = client["mystore"]

# Reference a collection inside it (also not yet on disk)
products = db["products"]

# The database and collection are created when the first document is inserted

Operazioni CRUD di base

Gli esempi seguenti si costruiscono uno sull'altro. Eseguili nell'ordine se stai seguendo in modo interattivo.

Create — inserire documenti

Usa insert_one() per un singolo documento e insert_many() per un batch:

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")
db = client["mystore"]
products = db["products"]

# Insert a single document
result = products.insert_one({
    "name": "Laptop",
    "brand": "Acme",
    "price": 999.99,
    "in_stock": True
})
print("Inserted id:", result.inserted_id)

# Insert multiple documents at once
new_products = [
    {"name": "Mouse",    "brand": "Acme", "price": 29.99,  "in_stock": True},
    {"name": "Keyboard", "brand": "Acme", "price": 79.99,  "in_stock": False},
    {"name": "Monitor",  "brand": "Zeta", "price": 349.99, "in_stock": True},
]
batch_result = products.insert_many(new_products)
print("Inserted ids:", batch_result.inserted_ids)

MongoDB aggiunge automaticamente un campo _id (di tipo ObjectId) a ogni documento se non ne fornisci uno. Questo campo è la chiave primaria ed è sempre univoco all'interno di una collection.

Read — interrogare i documenti

find_one() restituisce il primo documento corrispondente (o None). find() restituisce un cursore su cui puoi iterare.

# Retrieve one document (no filter = the first document in natural order)
doc = products.find_one()
print(doc)

# Retrieve all documents in the collection
for p in products.find():
    print(p["name"], "-", p["price"])

# Filter: products that are in stock
for p in products.find({"in_stock": True}):
    print(p["name"])

# Projection: return only name and price (exclude _id)
for p in products.find({}, {"_id": 0, "name": 1, "price": 1}):
    print(p)

Operatori di query

Il linguaggio di query di MongoDB usa operatori con prefisso $:

# Products cheaper than £100
cheap = products.find({"price": {"$lt": 100}})

# In-stock products from brand "Acme" or "Zeta"
multi = products.find({
    "in_stock": True,
    "brand": {"$in": ["Acme", "Zeta"]}
})

# Price between 50 and 500 (inclusive)
range_q = products.find({"price": {"$gte": 50, "$lte": 500}})

Operatori di confronto comuni:

OperatoreSignificato
$eqUguale (predefinito quando si usa {"field": value})
$neDiverso
$gt / $gteMaggiore di / maggiore o uguale a
$lt / $lteMinore di / minore o uguale a
$inIl valore è in una lista
$ninIl valore non è in una lista

Update — modificare i documenti

update_one() modifica il primo documento corrispondente. update_many() modifica tutte le corrispondenze. Usa sempre l'operatore $set per modificare campi specifici — senza di esso sostituiresti l'intero documento.

# Update a single document: change the price of "Mouse"
update_result = products.update_one(
    {"name": "Mouse"},          # filter
    {"$set": {"price": 24.99}}  # update
)
print("Matched:", update_result.matched_count,
      "Modified:", update_result.modified_count)

# Mark all Acme products as in stock
products.update_many(
    {"brand": "Acme"},
    {"$set": {"in_stock": True}}
)

# Increment a field value
products.update_one(
    {"name": "Laptop"},
    {"$inc": {"price": -50}}  # reduce price by 50
)

Operatori di aggiornamento comuni:

OperatoreEffetto
$setImposta uno o più campi
$unsetRimuove un campo
$incIncrementa un campo numerico
$pushAggiunge un valore a un campo array
$pullRimuove un valore da un campo array

Delete — rimuovere i documenti

delete_one() rimuove il primo documento corrispondente. delete_many() rimuove tutte le corrispondenze.

# Remove a single document
del_result = products.delete_one({"name": "Keyboard"})
print("Deleted count:", del_result.deleted_count)

# Remove all out-of-stock items
products.delete_many({"in_stock": False})

# Confirm what is left
print("Remaining products:")
for p in products.find({}, {"_id": 0, "name": 1}):
    print(" -", p["name"])

Errori comuni

La creazione lazy può nascondere i refusi

Poiché MongoDB crea database e collection su richiesta, un refuso crea silenziosamente un secondo database vuoto invece di generare un errore:

# Intended: client["mystore"]   Actual: client["mystoree"]
db = client["mystoree"]  # no error, but your data goes to the wrong database

Soluzione: definisci i nomi di database e collection come costanti a livello di modulo:

DB_NAME  = "mystore"
COL_NAME = "products"

db = client[DB_NAME]
products = db[COL_NAME]

Gli errori di connessione emergono solo alla prima operazione

MongoClient() ha successo anche quando MongoDB non è in esecuzione. L'errore appare solo quando effettui una richiesta concreta. Usa serverSelectionTimeoutMS e un controllo ping all'avvio (come mostrato nella sezione sulla connessione) per rilevare i problemi il prima possibile.

L'assenza di $set sostituisce l'intero documento

# WRONG — replaces the whole document with just {"price": 24.99}
products.update_one({"name": "Mouse"}, {"price": 24.99})

# CORRECT — only changes the price field
products.update_one({"name": "Mouse"}, {"$set": {"price": 24.99}})

find() restituisce un cursore, non una lista

Un cursore è lazy — i documenti vengono recuperati dal server solo mentre si itera. Se hai bisogno di una lista semplice, convertila esplicitamente:

all_products = list(products.find())

Presta attenzione con le collection di grandi dimensioni: caricare tutto in memoria in una sola volta può esaurire la RAM.

Cosa c'è dopo

Questo capitolo ha trattato gli elementi essenziali. Il resto della serie Python MongoDB approfondisce ogni argomento:

Was this page helpful?