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

Ottieni l'indice di un elemento all'interno della query mongodb

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 un finalize() 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.