Oltre le Basi: Comandi Avanzati di Query MongoDB per l'Analisi dei Dati
Utilizza filtri, proiezioni e fasi di aggregazione avanzati di MongoDB per analizzare i dati senza spostarli dal database.
Oltre le Basi: Comandi Avanzati di Query MongoDB per l'Analisi dei Dati
Le query MongoDB diventano più utili quando si va oltre le semplici chiamate find(). Se hai bisogno di filtrare documenti annidati, rimodellare l'output o calcolare risultati raggruppati, gli operatori di query avanzati e le fasi di aggregazione ti permettono di fare questo lavoro vicino ai dati.
Gli esempi seguenti si concentrano su comandi pratici che puoi eseguire in mongosh per report, risoluzione dei problemi e analisi una tantum.
Padroneggiare il Filtraggio Complesso con gli Operatori di Query
Mentre il metodo base find() gestisce semplici controlli di uguaglianza, l'analisi avanzata richiede spesso la combinazione di più condizioni o la query su strutture di campo specifiche. MongoDB fornisce un ricco set di operatori di query per costruire filtri granulari.
Operatori Logici per Query Composte
Gli operatori logici ti permettono di combinare più condizioni di query, offrendo un controllo granulare su quali documenti vengono restituiti. Sono essenziali per strutturare domande analitiche complesse.
$and/$andImplicito: Usato per specificare più criteri che devono essere tutti veri. Sebbene spesso implicito (elencando le condizioni in sequenza nell'oggetto query),$andè necessario quando si interroga lo stesso campo più volte.// $and implicito: Trova utenti con età maggiore di 25 E che vivono a New York db.users.find({ age: { $gt: 25 }, city: "New York" }); // $and esplicito: Trova documenti dove 'score' è > 90 O 'level' è 5 db.results.find({ $and: [ { score: { $gt: 90 } }, { level: 5 } ] });$or: Seleziona documenti che corrispondono a qualsiasi delle espressioni specificate nell'array.db.products.find({ $or: [ { category: "Electronics" }, { price: { $lt: 100 } } ] });$not: Nega i risultati dell'espressione specificata.
Operatori Geospaziali e per Array
Per dati basati sulla posizione o array complessi, operatori specializzati forniscono potenza analitica:
$geoWithin/$near: Essenziale per trovare dati all'interno di un'area geografica specifica o in prossimità.$elemMatch: Cruciale per interrogare array di documenti incorporati, assicurando che un elemento nell'array corrisponda a tutti i criteri specificati all'interno di$elemMatch.// Trova ordini dove almeno un articolo nell'array 'items' costa più di 500 E ha una quantità maggiore di 1 db.orders.find({ items: { $elemMatch: { price: { $gt: 500 }, qty: { $gt: 1 } } } });
Proiezione Avanzata: Modellare l'Output
La proiezione, gestita usando il secondo argomento nel metodo find(), determina quali campi vengono restituiti. La proiezione avanzata va oltre la semplice inclusione/esclusione per trasformare o modellare i dati restituiti.
Esclusione e Inclusione di Campi
1include un campo;0esclude un campo.- Nota Importante: Non puoi mescolare inclusione (
1) ed esclusione (0) tranne che per il campo_id(che è incluso per impostazione predefinita e può essere esplicitamente escluso impostandolo a0).
// Include solo 'name' e 'email', esclude '_id'
db.users.find({}, { name: 1, email: 1, _id: 0 });
Affettamento e Manipolazione di Array
La proiezione può limitare il numero di elementi dell'array restituiti usando $slice:
$slice: N: Restituisce i primi N elementi.$slice: -N: Restituisce gli ultimi N elementi.$slice: [M, N]: Restituisce N elementi a partire dall'indice M.
// Restituisce solo le ultime 3 voci dall'array 'history'
db.logs.find({}, { history: { $slice: -3 } });
Analizzare i Dati con il Framework di Aggregazione
Il Framework di Aggregazione di MongoDB è lo strumento più potente per l'analisi complessa dei dati, permettendoti di elaborare record di dati attraverso una pipeline di fasi. Ogni fase esegue una trasformazione o operazione specifica sui dati passati dalla fase precedente.
Fasi Chiave di Aggregazione
La struttura base usa db.collection.aggregate([...pipeline]).
1. $match (Filtraggio)
Funziona in modo simile a find(), ma viene applicato prima delle fasi successive, ottimizzando le prestazioni riducendo il dataset in anticipo.
2. $group (Raggruppamento e Calcolo)
Questa fase raggruppa i documenti per un identificatore specificato (_id) e applica operatori accumulatori per calcolare statistiche di riepilogo.
Accumulatori Comuni:
$sum$avg$min,$max$push(per raccogliere dati di array dal gruppo)
// Calcola il punteggio medio per dipartimento
db.scores.aggregate([
{ $group: {
_id: "$department",
averageScore: { $avg: "$score" },
totalStudents: { $sum: 1 }
} }
]);
3. $project (Rimodellamento dei Documenti)
Usato all'interno dell'aggregazione per rimodellare i documenti di output, simile alla proiezione di find(), ma spesso usato per creare nuovi campi calcolati.
- Campi Calcolati: Puoi eseguire calcoli all'interno della fase di proiezione usando campi esistenti.
// Calcola il margine di profitto all'interno della pipeline
db.sales.aggregate([
{ $project: {
_id: 0,
productName: 1,
profit: { $subtract: ["$salePrice", "$cost"] }
} }
]);
4. $lookup (Unione di Dati)
La fase $lookup aggiunge documenti corrispondenti da un'altra collezione, simile a un left outer join. È utile quando hai bisogno di arricchire i documenti per i report senza eseguire il join nel codice dell'applicazione.
// Unisce la collezione 'orders' con la collezione 'customers'
db.orders.aggregate([
{ $match: { status: "Pending" } },
{ $lookup: {
from: "customers", // Collezione con cui unire
localField: "customerId", // Campo dai documenti di input (orders)
foreignField: "_id", // Campo dai documenti della collezione "from" (customers)
as: "customerDetails" // Nome del campo array di output
} }
]);
5. $unwind (Decomposizione di Array)
Se un campo array contiene più elementi, $unwind crea un documento di output separato per ogni elemento nell'array, denormalizzando efficacemente i dati per un raggruppamento o filtraggio più facile sui contenuti dell'array.
Attenzione:
$unwindpuò aumentare significativamente il conteggio dei documenti. Usalo con giudizio, tipicamente dopo$matchper ridurre il set iniziale.
Migliori Pratiche per Query Analitiche
- Indicizza i Punti di Ingresso: Indicizza i campi usati dalle prime fasi
$matche dalle fasi$sortbasate su indici.$grouppuò beneficiare di meno documenti di input, ma non diventa automaticamente veloce solo perché il campo raggruppato ha un indice. - Filtra Presto: Posiziona le fasi
$matchil più presto possibile nella pipeline di aggregazione. Ridurre il conteggio dei documenti presto risparmia una potenza di elaborazione significativa per fasi successive più costose come$lookupo$group. - Usa Tipi di Dati Appropriati: Assicurati che i campi di confronto (come date o valori numerici) siano memorizzati in modo coerente. Disallineamenti di tipo causano il fallimento silenzioso o inefficiente degli operatori
$match.
Usa questi comandi quando il semplice recupero dei dati non è sufficiente. Inizia con filtri selettivi, proietta solo i campi di cui hai bisogno e passa all'aggregazione quando hai bisogno di raggruppamento, rimodellamento o arricchimento tra collezioni.