f in x
CRUD MongoDB con Node.js e Python: Operazioni Base e Best Practice da Produzione
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Sviluppo di siti web

CRUD MongoDB con Node.js e Python: Operazioni Base e Best Practice da Produzione

[2026-06-17] Author: Ing. Calogero Bono

Il tuo backend parla con MongoDB ma ogni volta che scrivi un find() o un insertOne() senti di poter fare di più? Succede. Il CRUD sembra banale, ma sbagliare un indice, dimenticare un try/catch o non gestire la connessione per le operazioni bulk costa caro in produzione. Noi, di Meteora Web, abbiamo visto progetti rallentare del 300% per una query scritta male e dati persi per mancanza di atomicità. Questa guida ti porta dal CRUD base a quello che funziona sul serio, con driver Node.js e Python, pronto per essere copiato e incollato nel tuo codice.

Il CRUD non è solo Inserisci-Leggi-Aggiorna-Cancella

Partiamo da uno scenario concreto: gestisci un catalogo prodotti per un e-commerce. Ogni giorno arrivanou nuovi articoli, aggiorni prezzi, cancelli prodotti fuori catalogo. In fase di sviluppo tutto fila liscio. Poi in produzione arriva il carico: 10.000 richieste al minuto, le scritture vanno in timeout, il database va in crash per connessioni aperte e non chiuse. Il problema non è MongoDB: è come gli parli. Il CRUD operativo non è solo scrivere query funzionanti, ma query efficienti, atomiche e resilienti.

Gestione della connessione: la prima vera CRUD

Non aprire una nuova connessione per ogni operazione. Usa un client pool condiviso. Ecco l’approccio giusto per Node.js con il driver mongodb:

Sponsored Protocol

const { MongoClient } = require('mongodb');

const uri = process.env.MONGODB_URI;
const client = new MongoClient(uri, { 
  maxPoolSize: 10, 
  serverSelectionTimeoutMS: 5000 
});

async function connectDB() {
  if (!client.isConnected()) await client.connect();
  return client.db('ecommerce');
}

module.exports = { connectDB };

Per Python con pymongo:

from pymongo import MongoClient
import os

uri = os.getenv('MONGODB_URI')
client = MongoClient(uri, maxPoolSize=10, serverSelectionTimeoutMS=5000)

def get_db():
    return client['ecommerce']

Perché conviene: il pool di connessioni evita di aprire e chiudere socket a ogni richiesta. Tempo di risposta medio si riduce del 70% rispetto a connessioni one-shot.

Create: InsertOne e InsertMany con controllo

Quando inserisci documenti, non fidarti mai dei dati in input senza validazione. Un campo price stringa al posto di number può rompere tutte le aggregazioni. Noi usiamo quasi sempre insertMany con ordered: false per batch di grandi dimensioni: se un documento fallisce, gli altri vengono inseriti comunque.

Sponsored Protocol

Node.js: insertMany ordinato vs non ordinato

const db = await connectDB();
const products = db.collection('products');

// Inserimento bulk con ordered: false
const docs = [
  { sku: 'P001', name: 'Maglietta', price: 29.99 },
  { sku: 'P002', name: 'Jeans', price: 79.99 },
  { sku: 'P001', name: 'Duplicato' } // fallirà su unique index, ma il resto passa
];

try {
  const result = await products.insertMany(docs, { ordered: false });
  console.log(`Inseriti ${result.insertedCount} documenti`);
} catch (e) {
  console.error('Errore su alcuni documenti:', e.writeErrors);
}

Python: insert_many con gestione errori

db = get_db()
products = db['products']

docs = [
    {'sku': 'P001', 'name': 'Maglietta', 'price': 29.99},
    {'sku': 'P002', 'name': 'Jeans', 'price': 79.99},
    {'sku': 'P001', 'name': 'Duplicato'}
]

try:
    result = products.insert_many(docs, ordered=False)
    print(f"Inseriti {len(result.inserted_ids)} documenti")
except pymongo.errors.BulkWriteError as e:
    print('Documenti falliti:', e.details['writeErrors'])

Errore comune: non gestire BulkWriteError fa crashare l'app. Con ordered: false eviti blocchi totali.

Sponsored Protocol

Read: find, findOne e proiezioni efficienti

Leggere senza criterio è il modo più veloce per far piangere il database. Usa sempre proiezioni per restituire solo i campi che servono e filtri con indici. In un e-commerce, per listare prodotti in homepage, non serve mandare i campi descrizione lunghi.

Node.js: query con proiezione e limit

const result = await products.find(
  { price: { $gte: 10, $lte: 100 } },
  { projection: { name: 1, price: 1, _id: 0 } }
).limit(20).toArray();

Python: idem

result = list(products.find(
    {'price': {'$gte': 10, '$lte': 100}},
    {'name': 1, 'price': 1, '_id': 0}
).limit(20))

Attenzione: se non metti limit in produzione, MongoDB legge tutti i documenti e poi butta via i 20 richiesti. Spreco di I/O.

Update: updateOne, updateMany e atomicità

Quando aggiorni uno stock, devi essere certo che due richieste simultanee non portino a vendite multiple dell’ultimo pezzo. Usa operatori atomici come $inc e $set.

Node.js: decremento atomico con controllo

const result = await products.updateOne(
  { sku: 'P001', stock: { $gt: 0 } },
  { $inc: { stock: -1 } }
);
if (result.modifiedCount === 0) {
  console.log('Prodotto esaurito o inesistente');
}

Python: idem

result = products.update_one(
    {'sku': 'P001', 'stock': {'$gt': 0}},
    {'$inc': {'stock': -1}}
)
if result.modified_count == 0:
    print('Prodotto esaurito o inesistente')

Perché conviene: l’operatore $inc è atomico. Se due richieste arrivano insieme, ognuna diminuisce di 1. Nessun doppione.

Sponsored Protocol

Delete: deleteOne, deleteMany e non solo

Cancellare è pericoloso. Noi adottiamo quasi sempre un soft delete tramite campo deletedAt, specialmente in contesti fiscali come la contabilità (e lo diciamo da ex contabili). Ma quando il delete è necessario, fallo con consapevolezza.

Node.js: deleteOne condizionale

const result = await products.deleteOne({ sku: 'P999', deletedAt: { $exists: false } });
if (result.deletedCount === 0) console.log('Documento non trovato');

Python: idem

result = products.delete_one({'sku': 'P999', 'deletedAt': {'$exists': False}})
if result.deleted_count == 0:
    print('Documento non trovato')

Errori comuni che vediamo nei progetti dei clienti

Abbiamo ereditato progetti dove:

Sponsored Protocol

  • Le connessioni venivano aperte e chiuse a ogni richiesta (lento).
  • Non c’erano indici su sku (ogni ricerca era una scansione completa).
  • Le scritture bulk erano ordinate (un errore e tutto il lotto veniva respinto).
  • Nessun controllo su modifiedCount — gli aggiornamenti fallivano in silenzio.

Per una trattazione completa dei pattern di progettazione, leggi la nostra guida pillar su MongoDB e NoSQL.

In sintesi — cosa fare adesso

  1. Rivedi la gestione della connessione: usa un pool condiviso in entrambi i driver.
  2. Inserisci sempre con ordered: false nei batch e gestisci BulkWriteError.
  3. Leggi con proiezione e limit — evita di trasportare dati inutili.
  4. Usa operatori atomici ($inc, $set, $push) per update concorrenti.
  5. Preferisci soft delete con campo deletedAt per reversibilità.

Il CRUD non è mai solo CRUD. È la base della solidità del tuo sistema. Noi, di Meteora Web, lo vediamo ogni giorno: un’app che scrive bene è un’app che scala. Se vuoi approfondire l’integrazione con driver specifici, consulta la documentazione ufficiale di Node.js o PyMongo.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere Informatico, co-fondatore di Meteora Web. Esperto in architetture software, sicurezza informatica e sviluppo sistemi scalabili.
[ Read Full Dossier ]

> METEORA_WEB // WEB AGENCY

Costruiamo la presenza digitale che la tua azienda merita.

Siti web, social, pubblicità online, e-commerce e hosting performante: ingegnerizzati con metodo da ingegneri informatici a Sciacca, per tutta Italia.

> MW_JOURNAL

> READ_ALL()