Normalmente, le applicazioni che usano i database hanno bisogno, per mostrare i dati agli utenti, sia delle funzioni di ricerca che di altri meccanismi, come l’ordinamento e la paginazione, in particolar modo quando i dati nel database sono molti. Infatti, è preferibile evitare di ordinare e paginare i dati nella memoria dell’applicazione, poiché ciò potrebbe provocare evidenti problemi di performance.
Formalmente MongoDB mette a disposizione queste operazioni come metodi dei cursori. Come abbiamo visto nella Lezione 6, quando si esegue un’interrogazione tramite il metodo find
, MongoDB non restituisce direttamente i documenti, bensì un cursore che può essere usato per scorrerli. Ad esempio:
db.eventi.find( { tipo: "ordineInviato" } );
Se usiamo la console Mongo, sarà essa stessa a scorrere per noi il cursore, mostrandoci il contenuto del database.
Quindi, in pratica, possiamo dire che queste funzioni vengono usate tutte le volte che si usa il metodo find
.
Ordinamento in base a uno o più campi
L’ordinamento del cursore può essere implementato tramite il metodo sort
. Esso prende in input un solo parametro che specifica quali campi usare nell’ordinamento. Ad esempio:
db.libri.find().sort({titolo: 1});
Il valore da specificare per ogni campo può essere:
-
1
per se si vuole ordinare in modo ascendente; -
-1
per se si vuole ordinare in modo discendente.
Se si specificano altri valori sarà generato un errore.
Se vengono specificati più campi, il cursore viene ordinato in base al primo di essi, poi a parità di valori per il secondo campo e così via se ne sono specificati altri, esattamente come avviene con la clausula ORDER BY
in SQL.
Ad esempio, con la seguente query i libri vengono ordinati in base al titolo, e a parità di titolo, l'ordinamento avviene per anno di pubblicazione, dal più recente al più vecchio:
db.libri.find().sort({titolo: 1, anno: -1});
Paginazione
La paginazione è molto importante quando si ha a che fare con grandi moli di dati. Soprattutto quando si sviluppano applicazioni Web, ridurre la quantità di dati che viaggiano tra i vari livelli della nostra applicazione (database, application server e browser) può essere cruciale per le prestazioni globali del sistema.
Un cursore di MongoDB può essere navigato con la paginazione usando i metodi skip
e limit
.
Il metodo limit
Questo metodo fa sì che il cursore restituisca soltanto un certo numero di elementi. Si può usare se vogliamo mostrare solo i primi n elementi restituiti da una query. Ad esempio, per i primi 20 libri del nostro database:
db.libri.find().sort({titolo: 1, anno: -1}).limit(20);
In pratica, viene abitualmente usato per indicare il numero di elementi per pagina.
Il metodo skip
Supponiamo ora di voler vedere i successivi 20 elementi. Ci serve, in questo caso, il metodo skip
per indicare al cursore di ignorare n elementi:
db.libri.find().sort({titolo: 1, anno: -1}).skip(20).limit(20);
Quindi, se vogliamo paginare una query e vogliamo vedere la quarta pagina, dobbiamo effettuare lo skip di 20*(4 - 1), posto che una pagina mostrerà 20 elementi:
db.libri.find().sort({titolo: 1, anno: -1}).skip(60).limit(20);
Conteggio dei dati
Per la paginazione, un'informazione importante è il numero di elementi da mostrare. Infatti, per sapere quante pagine saranno mostrate in totale dobbiamo dividere questo numero per il numero di elementi per pagina. Il metodo count
permette di ottenere questo valore:
db.libri.find().sort({titolo: 1, anno: -1}).count();