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.