Przeglądanie danych jest jedną z najczęstszych operacji w MongoDB. Typowym scenariuszem jest potrzeba wyświetlania wyników w kawałkach w interfejsie użytkownika. Jeśli przetwarzasz dane wsadowo, ważne jest również, aby Twoja strategia stronicowania była prawidłowa, aby przetwarzanie danych mogło się skalować.
Przejdźmy przez przykład, aby zobaczyć różne sposoby przeglądania danych w MongoDB. W tym przykładzie mamy bazę danych CRM z danymi użytkowników, które musimy przeglądać i wyświetlać jednocześnie 10 użytkowników. W efekcie nasz rozmiar strony wynosi 10. Oto struktura naszego dokumentu użytkownika:
{ _id, name, company, state }
Podejście 1:Używanie skip() i limit()
MongoDB natywnie obsługuje operację stronicowania za pomocą poleceń skip() i limit(). Dyrektywa skip(n) mówi MongoDB, że powinna pominąć „n” wyników, a dyrektywa limit(n) instruuje MongoDB, że powinna ograniczyć długość wyniku do „n” wyników. Zazwyczaj z kursorem będziesz używać dyrektyw skip() i limit() — ale aby zilustrować ten scenariusz, udostępniamy polecenia konsoli, które osiągną te same wyniki. Ponadto, ze względu na zwięzłość kodu, kod sprawdzania limitów jest również wykluczony:
//Page 1 db.users.find().limit (10) //Page 2 db.users.find().skip(10).limit(10) //Page 3 db.users.find().skip(20).limit(10) ........
Masz pomysł. Ogólnie, aby pobrać stronę ‘n’ kod wygląda tak:
db.users.find().skip(pagesize*(n-1)).limit(pagesize)
Jednak wraz ze wzrostem rozmiaru danych takie podejście wiąże się z poważnymi problemami z wydajnością. Powodem jest to, że za każdym razem, gdy wykonywane jest zapytanie, budowany jest pełny zestaw wyników, a następnie serwer musi przejść od początku kolekcji do określonego przesunięcia. Wraz ze wzrostem offsetu proces ten staje się coraz wolniejszy. Ponadto ten proces nie powoduje efektywnego wykorzystania indeksów. Dlatego zwykle podejście „skip()” i „limit()” jest przydatne, gdy masz małe zestawy danych, a jeśli pracujesz z dużymi zestawami danych, warto rozważyć inne podejścia.
Podejście 2:Używanie find() i limit()
Powodem, dla którego poprzednie podejście nie skaluje się zbyt dobrze, jest polecenie skip(), a celem tej sekcji jest zaimplementowanie stronicowania bez użycia polecenia „skip()”. W tym celu wykorzystamy naturalny porządek przechowywanych danych, takich jak znacznik czasu lub identyfikator przechowywany w dokumencie. W tym przykładzie użyjemy „_id” przechowywanego w każdym dokumencie. „_id” to struktura MongoDB ObjectID, która jest 12-bajtową strukturą zawierającą znacznik czasu, maszynę, identyfikator procesu, licznik itp. Ogólna idea jest następująca:
1. Pobierz _id ostatniego dokumentu na bieżącej stronie
2. Pobierz dokumenty większe niż ten „_id” na następnej stronie
//Page 1 db.users.find().limit(pageSize); //Find the id of the last document in this page last_id = ... //Page 2 users = db.users.find({'_id'> last_id}). limit(10); //Update the last id with the id of the last document in this page last_id = ...
Takie podejście wykorzystuje nieodłączną kolejność istniejącą w polu „_id”. Ponadto, ponieważ pole „_id” jest domyślnie indeksowane, wydajność operacji wyszukiwania jest bardzo dobra. Jeśli pole, którego używasz, nie jest zindeksowane, ucierpi na tym Twoja wydajność – dlatego ważne jest, aby upewnić się, że to pole jest zindeksowane.
Dodatkowo, jeśli chcesz posortować dane w określonej kolejności dla stronicowania, możesz również użyć klauzuli sort() z powyższą techniką. Ważne jest, aby upewnić się, że proces sortowania wykorzystuje indeks w celu uzyskania najlepszej wydajności. Możesz użyć sufiksu .explain() w zapytaniu, aby to określić:
users = db.users.find({'_id'> last_id}). sort(..).limit(10); //Update the last id with the id of the last document in this page last_id = ...
Jak zawsze, jeśli masz jakieś pytania lub komentarze, skontaktuj się z nami pod adresem [email protected].