Le query in MongoDB con­sen­to­no di cercare e ana­liz­za­re il database in modo rapido ed efficace. La struttura del metodo è molto logica e prevede l’uso di numerosi parametri con cui è possibile spe­ci­fi­ca­re le query.

Ricerca efficace all’interno delle raccolte

In quanto soluzione NoSQL basata su documenti, MongoDB fornisce la pos­si­bi­li­tà di ar­chi­via­re e gestire fa­cil­men­te anche grandi e diverse quantità di dati. Il sistema di gestione dei database è molto fles­si­bi­le e fa­cil­men­te scalabile in oriz­zon­ta­le.

Al contrario dei database re­la­zio­na­li, qui i dati vengono me­mo­riz­za­ti in documenti BSON (JSON binario) e rag­grup­pa­ti in raccolte. Per far sì che questo approccio funzioni davvero, sono necessari dei mec­ca­ni­smi di in­ter­ro­ga­zio­ne forti, capaci di filtrare il database e di pre­sen­ta­re solo le in­for­ma­zio­ni realmente ne­ces­sa­rie. In MongoDB, le query sono in grado di cercare in raccolte anche molto ra­mi­fi­ca­te e di fornire le in­for­ma­zio­ni de­si­de­ra­te.

Consiglio

L’uso di MongoDB per mezzo della shell ti crea troppa con­fu­sio­ne? Con MongoDB Compass hai a di­spo­si­zio­ne un’in­ter­fac­cia grafica gratuita che ne sem­pli­fi­ca la gestione.

Che cosa sono le query in MongoDB?

In MongoDB, le query co­sti­tui­sco­no uno strumento di facile utilizzo per la ricerca di strutture di dati complesse. Esse seguono regole logiche e fun­zio­na­no come le opzioni di filtro di­spo­ni­bi­li in molti siti web. In questo modo è possibile formulare la ricerca con estrema pre­ci­sio­ne e ottenere i risultati migliori. Questo aspetto è par­ti­co­lar­men­te im­por­tan­te perché MongoDB offre la pos­si­bi­li­tà di me­mo­riz­za­re molti tipi di dati diversi. In mancanza delle ne­ces­sa­rie opzioni di filtro, sarebbe difficile gestire il database in modo sod­di­sfa­cen­te. Di seguito de­scri­ve­re­mo come creare fa­cil­men­te query in MongoDB e come uti­liz­zar­le a proprio vantaggio.

Quali sono i requisiti per le query in MongoDB?

Per usufruire delle query in MongoDB sono necessari solo alcuni pre­re­qui­si­ti.

  1. Per prima cosa è ne­ces­sa­rio in­stal­la­re MongoDB sul computer. Il database funziona su molti sistemi operativi, perciò per queste istru­zio­ni non fa molta dif­fe­ren­za se utilizzi Linux, OS X o Windows. I passaggi suc­ces­si­vi all’in­stal­la­zio­ne sono gli stessi su tutti i sistemi e ri­guar­da­no solo il database stesso. Per sapere come funziona l’in­stal­la­zio­ne, consulta il nostro tutorial su MongoDB.
  2. Per la funzione di ricerca sono necessari anche i privilegi di am­mi­ni­stra­zio­ne.
  3. È con­si­glia­bi­le creare prima un ambiente di prova, in modo da poter provare il metodo senza rischi. Vediamo insieme come fare.

La struttura di una raccolta di prova

In primo luogo, apri la shell e accedi con i tuoi dati come am­mi­ni­stra­to­re o am­mi­ni­stra­tri­ce. Suc­ces­si­va­men­te, crea una nuova raccolta che fungerà da ambiente di prova per le prime query in MongoDB. Dal momento che il metodo può prendere in con­si­de­ra­zio­ne non solo documenti semplici, ma anche array, campi di vario genere e documenti integrati, rea­liz­ze­re­mo una raccolta un po’ più complessa per di­mo­stra­re la portata delle query in MongoDB.

Nel nostro esempio, si tratta di un elenco di clienti. Il formato dell’elenco sarà il seguente:

{
    "name" : "Rossi",
    "units" : 642,
    "location" : [ "Italy", "Austria" ],
    "transactions" : {
        "first" : {
            "year" : 2017,
        },
        "last" : {
            "year" : 2023,
        },
        "total" : 14
    }
}
shell

Il presente documento contiene le seguenti in­for­ma­zio­ni:

  • name: il nome dell’azienda cliente che ha ac­qui­sta­to la merce.
  • units: la quantità totale di prodotti ordinati dall’azienda.
  • location: la sede dell’altra azienda. Se ci sono più filiali, possono essere me­mo­riz­za­te sotto forma di array.
  • tran­sac­tions: in questo campo viene inserito un altro documento (in inglese si parla di “embedded documents” o “nested documents”). Ciascuno di questi documenti di tran­sa­zio­ne riporta in­for­ma­zio­ni su quanto tempo l’azienda è stata cliente (alla voce “first”), quando è stato ef­fet­tua­to l’ultimo ordine (alla voce “last”) e infine quante volte ha ordinato in totale (alla voce “total”).

In questo caso, i documenti ag­giun­ti­vi sono stati inseriti in modo da con­sen­ti­re l’aggiunta di ulteriori in­for­ma­zio­ni in un secondo momento. Ciò preserva la visione d’insieme.

Creare una raccolta di prova per le query in MongoDB

Ora creiamo una raccolta con il nome “Clienti”, che per il nostro esempio dovrebbe contenere solo cinque voci per una migliore visione d’insieme. Uti­liz­zan­do in modo pro­fes­sio­na­le le query in MongoDB in una fase suc­ces­si­va, è possibile creare raccolte molto più estese. Per farlo, si può ricorrere al metodo in­sert­Ma­ny. Nel nostro esempio, il metodo si presenta così:

db.clienti.insertMany ( [
{
    "name" : "Rossi",
    "units" : 642,
    "location" : [ "Italy", "Austria" ],
    "transactions" : {
        "first" : {
            "year" : 2017,
        },
        "last" : {
            "year" : 2023,
        },
        "total" : 14
    }
},
{
    "name" : "ATS",
    "units" : 17,
    "location" : "France",
    "transactions" : {
        "first" : {
            "year" : 2021,
        },
        "last" : {
            "year" : 2022,
        },
        "total" : 2,
    }
},
{
    "name" : "Meyer",
    "units" : 814,
    "location" : [ "Austria", "Italy" ],
    "transactions" : {
        "first" : {
            "year" : 2016,
        },
        "last" : {
            "year" : 2023,
        },
        "total" : 22,
    }
},
{
    "name" : "Pawolski",
    "units" : 313,
    "location" : [ "Italy", "Poland" ],
    "transactions" : {
            "first" : {
            "year" : 2017,
            },
        "last" : {
            "year" : 2020,
        },
        "total" : 9,
    }
},
{
    "name" : "Jorgensen",
    "units" : 7,
    "location" : "Denmark",
    "transactions" : {
        "first" : {
            "year" : 2022,
        },
        "last" : {
            "year" : 2023,
        },
        "total" : 2,
    }
}
] )
shell

Eseguendo l’input in questo modo o con i propri dati, in cambio verrà fornito un elenco degli ID degli oggetti assegnati. Si tratta di dati univoci, con i quali si ga­ran­ti­sce che ogni documento possa essere trovato tramite l’ID. Per as­si­cu­rar­ti che tutti i documenti siano stati tra­sfe­ri­ti nella raccolta, puoi avvalerti di MongoDB find e fare a meno di parametri ag­giun­ti­vi:

db.clienti.find ( )
shell

L’output è un elenco di tutti gli ID degli oggetti con i documenti completi, in cui è possibile ef­fet­tua­re ricerche con le query di MongoDB.

In­ter­ro­ga­re singoli campi con le query in MongoDB

Questo output da solo mette in evidenza il valore aggiunto offerto dalle query in MongoDB. Persino nel nostro semplice esempio, l’output produce lunghe stringhe di caratteri, rendendo molto difficile l’analisi senza l’ausilio di strumenti. Pertanto, anche dopo uti­liz­ze­re­mo il metodo find, spe­ci­fi­can­do però la nostra ricerca. A tale scopo, definiamo un requisito speciale che il documento deve sod­di­sfa­re per essere prodotto. Nell’esempio, cerchiamo tutti i documenti il cui nome cor­ri­spon­de al valore “ATS”. L’input da inserire è questo:

db.clienti.find (
    { "name" : "ATS" }
)
shell

Le semplici query in MongoDB di questo tipo ora ef­fet­tua­no una ricerca in tutti i documenti me­mo­riz­za­ti nella raccolta cor­ri­spon­den­te per trovare quelli che hanno il valore del nome “ATS”. Questa ope­ra­zio­ne riguarda solo una voce della nostra raccolta, per cui l’output si presenta in questo modo:

db.clienti.find ( { "name" : "ATS" } )
{
    "_id" : ObjectID ( "673d14684o75iftbb0ct5003" ),
    "name" : "ATS",
    "units" : 17,
    "location" : "France",
    "transactions" : {
        "first" : {
            "year" : 2021,
        },
        "last" : {
            "year" : 2022,
        },
        "total" : 2
    }
shell

Anche il metodo opposto funziona. Se vuoi vi­sua­liz­za­re tutti i risultati tranne la voce “ATS”, seleziona la voce seguente e otterrai di nuovo il risultato de­si­de­ra­to:

db.clienti.find (
    { "name" : { $ne : "ATS" } }
)
shell

Se invece desideri produrre query in MongoDB con valori diversi, puoi farlo anche con un array. Nel nostro esempio, con­si­de­ria­mo i clienti “ATS” e “Jorgensen”.

db.clienti.find (
    { "name" : [ $in : [ "ATS", "Jorgensen" ] } }
)
shell

In­ter­ro­ga­re più campi con le query in MongoDB

Per avere risultati ancora più precisi, tuttavia, è ne­ces­sa­rio spe­ci­fi­ca­re ul­te­rior­men­te la query. Le query in MongoDB possono essere spe­ci­fi­ca­te in modo ancora più preciso uti­liz­zan­do parametri ag­giun­ti­vi. Spe­ci­fi­can­do ora il valore del segmento “units” oltre al nome dell’azienda “ATS” per una query, viene ricercato un documento che contiene entrambi i valori:

db.clienti.find (
    { "name" : "ATS", "units" : 17 }
)
shell

Anche in questo caso c’è una cor­ri­spon­den­za esatta. Se però uno dei due valori non è corretto, non verrà emesso alcun risultato in questo modo. Ad esempio, il seguente input non avrà successo:

db.clienti.find (
    { "name" : "ATS", "units" : 25 }
)
shell

Per uti­liz­za­re invece le query in MongoDB così da prendere in con­si­de­ra­zio­ne valori diversi e inserire una voce già presente se almeno uno dei requisiti è sod­di­sfat­to, immetti il comando seguente:

db.clienti.find (
    { $or : [ {"name" : "ATS"}, { "units" : 25 } ] }
)
shell

In­ter­ro­ga­re i valori negli array

I valori negli array possono essere presi in con­si­de­ra­zio­ne anche con le query in MongoDB. Nell’esempio, ci sono aziende che hanno filiali in diversi paesi. Per vi­sua­liz­za­re tutti i clienti che hanno almeno una filiale in Italia, l’input è molto semplice:

db.clienti.find (
    { "location" : "Italy" }
)
shell

L’output include ora tutti e tre i clienti che hanno almeno una filiale in Italia. Se però desideri espandere l’input e re­cu­pe­ra­re con­tem­po­ra­nea­men­te tutti i clienti con filiali in Italia e in Austria, usa un array:

db.clienti.find (
    { "location" : [ "Italy", "Austria" ] }
)
shell

Noterai però che questo input mostra un solo risultato, anche se in teoria sono due le aziende che cor­ri­spon­do­no ai criteri di ricerca. Il motivo è che le query di MongoDB tengono conto dell’input esatto e quindi, in questo caso, dell’ordine. Se quindi vuoi con­si­de­ra­re valori che possono essere in qualsiasi ordine in un array, puoi com­ple­ta­re la query come segue:

db.clienti.find (
    { "location" : { $all : [ "Italy", "Austria" ] } }
)
shell

Query in MongoDB per documenti in­cor­po­ra­ti

Nel nostro esempio abbiamo uti­liz­za­to anche documenti in­cor­po­ra­ti. Anche questi possono essere re­sti­tui­ti con le query in MongoDB. A tale scopo, è ne­ces­sa­rio ag­giun­ge­re un punto per segnalare a MongoDB che i campi di un documento in­cor­po­ra­to devono essere ana­liz­za­ti. Ad esempio, se de­si­de­ria­mo un elenco di tutti i clienti che hanno più di dieci tran­sa­zio­ni di ordine, inseriamo questo elemento:

db.clienti.find (
    { "transactions.total" : { $gt : 10 } }
)
shell

Questo è il modo in cui MongoDB accede al documento “tran­sac­tions” e poi prende in con­si­de­ra­zio­ne il numero di tran­sa­zio­ni dell’ordine alla voce “total”.

Limitare l’output delle query

Anche con i metodi appresi finora, il risultato delle query in MongoDB può essere molto esteso. Di con­se­guen­za, può essere utile limitare l’output a pochi campi. A tale scopo si uti­liz­za­no le co­sid­det­te pro­ie­zio­ni. Esse con­ten­go­no il valore 1 (per i campi inclusi) e 0 (per i campi da escludere). Nell’esempio che segue, rea­liz­zia­mo una query in due parti. In­nan­zi­tut­to, viene avviata una ricerca senza parametri, che con­ter­reb­be tutte le in­for­ma­zio­ni. Im­me­dia­ta­men­te dopo, però, viene ef­fet­tua­ta una pro­ie­zio­ne che prende in con­si­de­ra­zio­ne solo il campo del nome.

db.clienti.find (
    { }
    { "name" : 1 }
)
shell

Così facendo si ot­ter­ran­no tutti i risultati, ma l’output sarà limitato ai ri­spet­ti­vi nomi.

Uti­liz­za­re i cursori per ot­ti­miz­za­re l’output

I cursori non sono un metodo per regolare i risultati delle query in MongoDB, ma per per­so­na­liz­zar­ne la vi­sua­liz­za­zio­ne. Per esempio, è possibile limitare il numero di risultati o mo­di­fi­car­ne l’ordine. Per vi­sua­liz­za­re solo due risultati, utilizza il metodo limit. Funziona così:

db.clienti.find (
    { }
    { "name" : 1 }
).limit ( 2 )
shell

Per ordinare l’output, serviti della seguente voce. Saranno vi­sua­liz­za­te le tre persone che hanno ordinato il minor numero di prodotti:

db.clienti.find (
    { }
    { "name" : 1 }
).limit ( 2 ) .sort ( { "units" : 1 } )
shell
Consiglio

Per trovare un documento specifico nel database, puoi uti­liz­za­re il metodo MongoDB findONE. Consulta l’articolo della nostra Digital Guide per scoprire come funziona questo metodo nel dettaglio.

Vai al menu prin­ci­pa­le