Zamawianie według identyfikatora podmiotu
Jeśli Twój subjectID jest (lub można go zmienić na) monotonicznie rosnącą wartością (na przykład domyślnym ObjectID MongoDB), masz prostą opcję przy użyciu normalnego find() z odpowiednim sortowaniem, pomijaniem i ograniczaniem. W takim przypadku możesz szukać dokumentów z identyfikatorami podmiotu $gte (większe lub równe)
Twój subjectID :
var page = 1;
var subjectID = ObjectId("515535a0760fe8735f5f6897");
db.users.find(
{ _id: { $gte : subjectID } }
).sort({'_id':1}).skip(page*20).limit(20)
Struktura agregacji
Podobnie jak w MongoDb 2.4, w ramach agregacji nie ma takiej funkcji, która umożliwiałaby dopasowanie na podstawie pozycji dokumentu w potoku wyników. Możesz zgłosić nową propozycję funkcji SERWER projektu MongoDB Jira kolejka.
Wygląda na to, że potrzebujesz nowego operatora potoku, takiego jak $matchfrom co zignoruje wszystkie dokumenty do pierwszego wystąpienia $matchfrom kryteria. Następnie możesz dodać $limit do podjęcia kolejnych n pozycji. Chciałbyś również mieć posortowane dane wyjściowe przed $matchfrom więc jest przewidywalny wynik.
Wydaje się to zbyt skomplikowane w porównaniu z rosnącym identyfikatorem podmiotu, ale może istnieć przypadek użycia stronicowania w oparciu o bardziej zaawansowane kryteria wyszukiwania lub wyniki obliczane w potoku agregacji.
Alternatywne podejścia
Oprócz przyszłej obsługi takiej funkcji w ramach agregacji, masz kilka opcji zaimplementowania tego samego podejścia do dopasowywania w kodzie:
-
użyj starszego
group()polecenie agregacji zfinalize()funkcjonować. UWAGA:group()czy nie pracuj z klastrami podzielonymi na fragmenty. -
użyj MapReduce i
finalize()funkcja -
pobierz cały zestaw wyników z agregacji Framework i zaimplementuj dopasowywanie/redukcję wyników w kodzie aplikacji (chociaż to nieco obala pojęcie „stronicowania”, jeśli pobierasz wszystkie strony dla każdego żądania).
Zagadnienia dotyczące wydajności
Zapytania z skip nadal trzeba czytać między wpisami w indeksie, więc pomijanie dużej liczby dokumentów nie będzie zbyt wydajne.
Zamiast stronicowania z przesunięciem pominięcia, możesz rozważyć wykonywanie kolejnych zapytań dotyczących stron, zaczynając od ostatniego wpisu na poprzedniej stronie (tj. pierwszą stroną będzie $gte początkowy identyfikator tematu i kolejne strony to $gt ostatni identyfikator podmiotu zawarty na poprzedniej stronie). Będzie to zależeć od sposobu prezentacji stronicowania w interfejsie użytkownika — najłatwiej byłoby zastosować to podejście, jeśli interfejs użytkownika ma tylko opcję wyświetlania „następnej” strony wiadomości, a nie przeskakiwania do określonej strony.