2013-01-10 11 views
6

Ho familiarità con la best practice di range based pagination su grandi raccolte MongoDB, tuttavia sto cercando di capire come impaginare una raccolta in cui il valore di ordinamento si trova su un campo non univoco.MongoDB - Impaginazione basata su campi non univoci

Ad esempio, ho una vasta collezione di utenti e c'è un campo per il numero di volte in cui hanno fatto qualcosa. Questo campo è decisamente non unico e potrebbe contenere grandi gruppi di documenti con lo stesso valore.

Desidero restituire i risultati ordinati in base al campo "numTimesDoneSomething".

Qui è un insieme di dati di esempio:

{_id: ObjectId("50c480d81ff137e805000003"), numTimesDoneSomething: 12} 
{_id: ObjectId("50c480d81ff137e805000005"), numTimesDoneSomething: 9} 
{_id: ObjectId("50c480d81ff137e805000006"), numTimesDoneSomething: 7} 
{_id: ObjectId("50c480d81ff137e805000007"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000002"), numTimesDoneSomething: 15} 
{_id: ObjectId("50c480d81ff137e805000008"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000009"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000004"), numTimesDoneSomething: 12} 
{_id: ObjectId("50c480d81ff137e805000010"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000011"), numTimesDoneSomething: 1} 

Come faccio a restituire questo insieme di dati ordinati da 'numTimesDoneSomething' con 2 record per pagina?

risposta

5

@cubbuk mostra un buon esempio utilizzando offset (skip), ma si può anche modellare la query egli mostra per l'impaginazione spaziato così:

db.collection.find().sort({numTimesDoneSomething:-1, _id:1}) 

Dal momento che l'_id qui sarà unica e si è in secondo luogo su di esso è quindi possibile intervallo da _id e i risultati, anche tra due record con numTimesDoneSomething di 12, devono essere coerenti se devono essere in una pagina o la successiva.

Così facendo qualcosa di semplice come

var q = db.collection.find({_id: {$gt: last_id}}).sort({numTimesDoneSomething:-1, _id:1}).limit(2) 

Dovrebbe funzionare abbastanza buono per l'impaginazione a distanza.

+0

Non 'troverà ({_ id: last_id})' mi restituirà solo un singolo record? La query di ricerca –

+1

deve essere maggiore di last_id, non è vero? La tua soluzione copre anche il caso di nuovi inserimenti +1 per quello =) – cubbuk

+1

@cubbuk Oh sì vero lol :) – Sammaye

2

È possibile ordinare su più campi in questo caso ordinare sui campi numTimesDoneSomething e id. Poiché il campo id_ è in ordine crescente già in base al timestamp di inserimento, è possibile eseguire la paginazione attraverso la raccolta senza iterare su dati duplicati a meno che non vengano inseriti nuovi dati durante l'iterazione.

db.collection.find().sort({numTimesDoneSomething:-1, _id:1}).offset(index).limit(2) 
Problemi correlati