MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Paging veloce con MongoDB

Il paging dei tuoi dati è una delle operazioni più comuni con MongoDB. Uno scenario tipico è la necessità di visualizzare i risultati in blocchi nell'interfaccia utente. Se stai elaborando i tuoi dati in batch, è anche importante che la tua strategia di paging sia corretta in modo che l'elaborazione dei dati possa scalare.

Esaminiamo un esempio per vedere i diversi modi per scorrere i dati in MongoDB. In questo esempio, abbiamo un database CRM di dati utente che dobbiamo sfogliare e visualizzare 10 utenti alla volta. Quindi, in effetti, la dimensione della nostra pagina è 10. Ecco la struttura del nostro documento utente:

{
    _id,
    name,
    company,
    state
}

Approccio 1:utilizzo di skip() e limit()

MongoDB supporta nativamente l'operazione di paging utilizzando i comandi skip() e limit(). La direttiva skip(n) dice a MongoDB che dovrebbe saltare 'n' risultati e la direttiva limit(n) indica a MongoDB che dovrebbe limitare la lunghezza del risultato a 'n' risultati. In genere, utilizzerai le direttive skip() e limit() con il cursore  - ma per illustrare lo scenario, forniamo comandi della console che otterrebbero gli stessi risultati. Inoltre, per brevità di codice, è escluso anche il codice di controllo dei limiti:

//Page 1
db.users.find().limit (10)
//Page 2
db.users.find().skip(10).limit(10)
//Page 3
db.users.find().skip(20).limit(10)
........

Ti viene l'idea. In generale, per recuperare la pagina 'n' il codice appare così:

db.users.find().skip(pagesize*(n-1)).limit(pagesize)

Tuttavia, con l'aumento delle dimensioni dei tuoi dati, questo approccio presenta seri problemi di prestazioni. Il motivo è che ogni volta che viene eseguita la query, viene creato il set di risultati completo, quindi il server deve camminare dall'inizio della raccolta all'offset specificato. All'aumentare dell'offset, questo processo diventa sempre più lento. Inoltre, questo processo non utilizza in modo efficiente gli indici. Quindi in genere l'approccio "skip()" e "limit()" è utile quando si hanno piccoli set di dati e se si lavora con set di dati di grandi dimensioni, ti consigliamo di prendere in considerazione altri approcci.

Approccio 2:utilizzo di find() e limit()

Il motivo per cui l'approccio precedente non scala molto bene è il comando skip() e l'obiettivo in questa sezione è implementare il paging senza usare il comando 'skip()'. Per questo, sfrutteremo l'ordine naturale nei dati archiviati come un timestamp o un ID archiviato nel documento. In questo esempio, utilizzeremo '_id' memorizzato in ogni documento. '_id' è una struttura MongoDB ObjectID che è una struttura a 12 byte contenente un timestamp, un elaborato, un processo, un contatore, ecc. L'idea generale è la seguente:

1. Recupera l'_id dell'ultimo documento nella pagina corrente
2. Recupera i documenti più grandi di questo "_id" nella pagina successiva

//Page 1
db.users.find().limit(pageSize);
//Find the id of the last document in this page
last_id = ...

//Page 2
users = db.users.find({'_id'> last_id}). limit(10);
//Update the last id with the id of the last document in this page
last_id = ...

Questo approccio sfrutta l'ordine intrinseco che esiste nel campo "_id". Inoltre, poiché il campo "_id" è indicizzato per impostazione predefinita, le prestazioni dell'operazione di ricerca sono molto buone. Se il campo che stai utilizzando non è indicizzato, le tue prestazioni ne risentiranno, quindi è importante assicurarsi che quel campo sia indicizzato.

Inoltre, se desideri che i tuoi dati vengano ordinati in un ordine particolare per il tuo paging, puoi anche utilizzare la clausola sort() con la tecnica sopra. È importante assicurarsi che il processo di ordinamento sfrutti un indice per ottenere le migliori prestazioni. Puoi utilizzare il suffisso .explain() per la tua query per determinare questo:

users = db.users.find({'_id'> last_id}). sort(..).limit(10);
//Update the last id with the id of the last document in this page
last_id = ...

Come sempre, se hai domande o commenti, non esitare a contattarci all'indirizzo [email protected].