2013-01-10 8 views
6

Jestem zaznajomiona z najlepszą praktyką range based pagination w dużych kolekcjach MongoDB, jednak mam problem z wymyśleniem w jaki sposób paginować kolekcję, w której wartość sortowania znajduje się na nieunikalnym polu.MongoDB - Paginacja oparta na nieunikalnych polach

Na przykład mam dużą kolekcję użytkowników i istnieje pole do tego, ile razy coś zrobili. To pole jest z pewnością nieunikalne i może zawierać duże grupy dokumentów o tej samej wartości.

Chciałbym zwrócić wyniki posortowane według tego pola "numTimesDoneSomething".

Oto przykładowy zestaw danych:

{_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} 

Jak wrócę to zestaw danych posortowanych według „numTimesDoneSomething” z 2 rekordów na stronie?

Odpowiedz

5

@cubbuk pokazuje dobry przykład przy użyciu offset (skip), ale można również kształtować zapytanie on pokazuje na wahały paginacji, a także:

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

Od czasu _id tutaj będzie wyjątkowy i jesteś na tej podstawie można w rzeczywistości uzyskać zakres od _id, a wyniki, nawet między dwoma rekordami mającymi numTimesDoneSomething z 12, powinny być spójne, czy powinny znajdować się na jednej stronie, czy w następnej.

więc robi coś tak prostego jak

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

Powinna działać całkiem dobrze dla wahały paginacji.

+0

Czy 'find ({_ id: last_id})' nie zwróci mi tylko jednego rekordu? –

+1

zapytanie musi być większe niż last_id, prawda? Twoje rozwiązanie obejmuje również przypadek nowych wstawek +1 dla tego =) – cubbuk

+1

@cubbuk O tak, prawda lol :) – Sammaye

2

Można sortować na wiele pól w tym przypadku sortowania w polu numTimesDoneSomething i id. Ponieważ pole id_ jest samo w sobie wznoszące się zgodnie ze znacznikiem czasu wstawiania, będzie można dokonać paginacji w kolekcji bez powtarzania nad duplikatami danych, chyba że podczas iteracji zostaną wstawione nowe dane.

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