Ordine per subjectID
Se il tuo subjectID
è (o può essere modificato in) un valore monotonicamente crescente (ad esempio, un ObjectID predefinito di MongoDB), hai un'opzione semplice usando un normale find()
con l'ordinamento, il salto e il limite appropriati. In questo caso puoi cercare documenti con subjectID $gte
(maggiore o uguale a)
il tuo subjectID
:
var page = 1;
var subjectID = ObjectId("515535a0760fe8735f5f6897");
db.users.find(
{ _id: { $gte : subjectID } }
).sort({'_id':1}).skip(page*20).limit(20)
Quadro di aggregazione
Come in MongoDb 2.4, non esiste una tale funzionalità nel Framework di aggregazione che corrisponda in base alla posizione del documento nella pipeline dei risultati. È possibile presentare un suggerimento per una nuova funzionalità al SERVER del progetto MongoDB Jira coda.
Sembra che tu voglia un nuovo operatore di pipeline come $matchfrom
che ignorerebbe tutti i documenti fino alla prima occorrenza di $matchfrom
criteri. Puoi quindi aggiungere un $limit
per prendere i prossimi n elementi. Vorresti anche avere l'output ordinato prima di $matchfrom
quindi c'è un risultato prevedibile.
Sembra complicato rispetto all'avere un subjectID crescente, ma potrebbe esserci un caso d'uso per eseguire il paging in base a criteri di ricerca più avanzati o risultati calcolati nella pipeline di aggregazione.
Approcci alternativi
Oltre al supporto futuro per tale funzionalità nel Framework di aggregazione, hai alcune opzioni per implementare lo stesso approccio di corrispondenza nel codice:
-
usa il vecchio
group()
comando di aggregazione con unfinalize()
funzione. NOTA:group()
non lavorare con i cluster partizionati. -
usa MapReduce e un
finalize()
funzione -
recupera l'intero set di risultati dal framework di aggregazione e implementa la corrispondenza/riduzione dei risultati nel codice dell'applicazione (sebbene ciò sconfigga in qualche modo la nozione di "paginazione" se stai recuperando tutte le pagine per ogni richiesta).
Considerazioni sulle prestazioni
Query con skip
devi ancora leggere le voci di indice intermedie, quindi saltare un gran numero di documenti non sarà molto efficiente.
Invece di eseguire il paging con uno skip offset, potresti considerare di eseguire query di pagina successive partendo dall'ultima voce della pagina precedente (cioè la prima pagina sarebbe $gte
il subjectID iniziale e le pagine successive sarebbero $gt
l'ultimo subjectID incluso nella pagina precedente). Ciò dipenderà da come si presenta il paging nell'interfaccia utente:sarebbe più semplice utilizzare questo approccio se l'interfaccia utente ha solo la possibilità di mostrare la pagina "successiva" dei messaggi anziché passare a una pagina specifica.