Jak MongoDB sortuje rekordy, gdy nie określono kolejności sortowania?

103

Kiedy uruchamiamy zapytanie Mongo find () bez określonej kolejności sortowania, czego wewnętrznie używa baza danych do sortowania wyników?

Zgodnie z dokumentacją na stronie mongo :

Podczas wykonywania funkcji find () bez parametrów, baza danych zwraca obiekty w naturalnym porządku do przodu.

W przypadku standardowych tabel porządek naturalny nie jest szczególnie przydatny, ponieważ chociaż kolejność jest często zbliżona do kolejności reklamowej, nie ma gwarancji, że będzie. Jednak w przypadku kolekcji limitowanych kolejność reklamowa jest gwarantowana jako kolejność naturalna. Może to być bardzo przydatne.

Jednak w przypadku kolekcji standardowych (kolekcji bez ograniczeń) jakie pole jest używane do sortowania wyników? Czy to pole _id czy coś innego?

Edytować:

Zasadniczo wydaje mi się, że próbuję uzyskać, jeśli wykonam następujące zapytanie wyszukiwania:

db.collection.find({"x":y}).skip(10000).limit(1000);

Czy w dwóch różnych momentach czasu: t1 i t2 otrzymam różne zestawy wyników:

  1. Kiedy nie było żadnych dodatkowych zapisów między t1 i t2?
  2. Kiedy pojawiły się nowe zapisy między t1 i t2?
  3. Czy są nowe indeksy, które zostały dodane między t1 i t2?

Przeprowadziłem kilka testów na tymczasowej bazie danych i otrzymałem takie same wyniki ( Tak ) dla wszystkich 3 przypadków - ale chciałem mieć pewność i jestem pewien, że moje przypadki testowe nie były zbyt dokładne.

saurabhj
źródło

Odpowiedzi:

121

Jaka jest domyślna kolejność sortowania, jeśli nie została określona?

Domyślna wewnętrzna kolejność sortowania (lub naturalna kolejność ) to niezdefiniowany szczegół implementacji. Utrzymywanie porządku jest dodatkowym obciążeniem dla silników pamięci masowej, a interfejs API MongoDB nie wymaga przewidywalności poza jawnym sort()lub specjalnym przypadkiem zbiorów o ustalonych limitach, które mają powiązane ograniczenia użytkowania . W przypadku typowych obciążeń pożądane jest, aby silnik pamięci masowej próbował ponownie wykorzystać dostępne wstępnie przydzielone miejsce i podejmował decyzje dotyczące najbardziej wydajnego przechowywania danych na dysku iw pamięci.

Bez kryteriów zapytania, wyniki zostaną zwrócone przez mechanizm przechowywania w naturalnej kolejności (czyli w kolejności, w jakiej zostały znalezione ). Kolejność wyników może pokrywać się z zamówieniem reklamowym, ale to zachowanie nie jest gwarantowane i nie można na nim polegać (poza kolekcjami ograniczonymi).

Kilka przykładów, które mogą wpływać na porządek przechowywania (naturalny):

  • WiredTiger używa innej reprezentacji dokumentów na dysku niż w pamięci podręcznej, więc naturalna kolejność może się zmieniać w oparciu o wewnętrzne struktury danych.
  • Oryginalny silnik pamięci MMAPv1 (usunięty w MongoDB 4.2) przydziela miejsce na rekordy dla dokumentów na podstawie reguł dopełniania. Jeśli dokument wykroczy poza aktualnie przydzielone miejsce na nagrania, wpłynie to na lokalizację dokumentu (i naturalną kolejność). Nowe dokumenty mogą być również umieszczane w magazynie oznaczonym jako dostępne do ponownego wykorzystania z powodu usuniętych lub przeniesionych dokumentów.
  • Replikacja używa idempotentnego formatu oplog , aby konsekwentnie stosować operacje zapisu na elementach zestawu replik. Każdy członek zestawu replik przechowuje lokalne pliki danych, które mogą się różnić w naturalnej kolejności, ale będą miały taki sam wynik po zastosowaniu aktualizacji oplog.

A jeśli używany jest indeks?

Jeśli używany jest indeks, dokumenty zostaną zwrócone w kolejności, w jakiej zostały znalezione (co musi być zgodne z kolejnością wstawiania lub kolejnością we / wy). Jeśli używany jest więcej niż jeden indeks, kolejność zależy wewnętrznie od tego, który indeks jako pierwszy zidentyfikował dokument podczas procesu deduplikacji.

Jeśli chcesz mieć przewidywalną kolejność sortowania, musisz dołączyć jawne sort()zapytanie i mieć unikalne wartości dla klucza sortowania.

Jak ograniczone kolekcje utrzymują kolejność reklamową?

Wyjątek implementacji odnotowany dla porządku naturalnego w kolekcjach ograniczonych jest wymuszany przez ich specjalne ograniczenia użytkowania: dokumenty są przechowywane w kolejności wstawienia, ale istniejącego rozmiaru dokumentu nie można zwiększyć, a dokumentów nie można jawnie usunąć. Zamawianie jest częścią ograniczonego projektu kolekcji, który zapewnia, że ​​najstarsze dokumenty „starzeją się” jako pierwsze.

Stennie
źródło
4
Czy to oznacza, że ​​jeśli uruchomię to samo polecenie wyszukiwania: db.collection.find ({"x": y}). Skip (20000) .limit (1000) w dwóch różnych punktach w czasie, otrzymam inny wynik zestawy? Co się stanie, jeśli nie było żadnych zapisów między dwoma poleceniami?
saurabhj
6
@saurabhj: Dodano kilka przykładów, które wpłyną na naturalny porządek. Jeśli dokumenty zostały przeniesione / usunięte, możesz otrzymać różne zestawy wyników. Jeśli nie było wstawiania / aktualizacji / usuwania dokumentów, powinieneś otrzymać ten sam wynik. Dodanie indeksów nie wpływa na lokalizację dokumentów na dysku.
Stennie
7
Należy również dodać zastrzeżenie, że w przypadku korzystania z replikacji naturalna kolejność może się różnić między elementami zestawu replik.
Stennie
Czy ktoś wie, jak wymusić którykolwiek z 2 skomentowanych tutaj punktów? Próbowaliśmy modyfikować dokumenty, ale nadal są zwracane w kolejności reklamowej ... Ciekawe, czy kolejność naturalna może się różnić od kolejności reklamowej.
Ferran Maylinch
Wymuszenie domyślnej kolejności (np. {createdAt: -1}) Jest konieczne do zaimplementowania optymistycznych wzorców UI (aktualizowanie list danych w pamięci podręcznej bez oczekiwania na odpowiedź serwera po utworzeniu / aktualizacji / usunięciu). W przeciwnym razie nie można dopasować optymistycznej kolejności po stronie klienta i kolejności odpowiedzi serwera.
Eric Burel
8

Jest zwracany w kolejności zapisanej (kolejność w pliku), ale nie ma gwarancji, że znajduje się we wstawionej kolejności. Nie są sortowane według pola _id. Czasami może to wyglądać, jakby zostało posortowane według kolejności reklam, ale może się zmienić w innym żądaniu. To nie jest wiarygodne.

Parvin Gasimzade
źródło