Możesz myśleć o indeksie jednopolowym MongoDB jak o tablicy ze wskaźnikami do lokalizacji dokumentów. Na przykład, jeśli masz kolekcję z (pamiętaj, że sekwencja jest celowo niewłaściwa):
[collection]
1: {a:3, b:2}
2: {a:1, b:2}
3: {a:2, b:1}
4: {a:1, b:1}
5: {a:2, b:2}
Indeks jednopolowy
Teraz, jeśli to zrobisz:
db.collection.createIndex({a:1})
Indeks w przybliżeniu wygląda tak:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Zwróć uwagę na trzy ważne rzeczy:
- Jest posortowany według
a
rosnąco - Każde wejście wskazuje na lokalizację, w której znajdują się odpowiednie dokumenty
- Indeks rejestruje tylko wartości
a
pole.b
pole w ogóle nie istnieje w indeksie
Więc jeśli zrobisz zapytanie takie jak:
db.collection.find().sort({a:1})
Wystarczy, że przejdziesz po indeksie od góry do dołu, pobierając i wyprowadzając dokument, na który wskazują wpisy. Zwróć uwagę, że możesz również przejść indeks od dołu, np.:
db.collection.find().sort({a:-1})
a jedyną różnicą jest chodzenie po indeksie w odwrotnej kolejności.
Ponieważ b
w ogóle nie ma w indeksie, nie możesz użyć indeksu podczas zapytań o b
.
Indeks złożony
W indeksie złożonym np.:
db.collection.createIndex({a:1, b:1})
Oznacza to, że chcesz sortować według a
najpierw sortuj według b
. Indeks wyglądałby tak:
[index a:1, b:1]
1: {a:1, b:1} --> 4
2: {a:1, b:2} --> 2
3: {a:2, b:1} --> 3
4: {a:2, b:2} --> 5
5: {a:3, b:2} --> 1
Pamiętaj, że:
- Indeks jest posortowany od
a
- W każdym
a
masz posortowaneb
- Masz 5 wpisów indeksu w porównaniu z tylko trzema w poprzednim przykładzie z jednym polem
Używając tego indeksu, możesz wykonać zapytanie takie jak:
db.collection.find({a:2}).sort({b:1})
Może łatwo znaleźć, gdzie a:2
następnie przejdź indeksem do przodu. Biorąc pod uwagę ten indeks, nie możesz tego zrobić :
db.collection.find().sort({b:1})
db.collection.find({b:1})
W obu zapytaniach nie możesz łatwo znaleźć b
ponieważ jest rozrzucony po całym indeksie (tj. Nie w ciągłych wpisach). Jednak możesz zrobić:
db.collection.find({a:2}).sort({b:-1})
ponieważ zasadniczo możesz znaleźć, gdzie a:2
są i przejdź przez b
wpisy wstecz.
Edytuj :wyjaśnienie pytania @marcospgp w komentarzu:
Możliwość korzystania z indeksu {a:1, b:1}
aby spełnić find({a:2}).sort({b:-1})
faktycznie ma sens, jeśli patrzysz na to z posortowanego punktu widzenia. Na przykład indeks {a:1, b:1}
można traktować jako:
a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
znajdź({a:2}).sortuj({b:1})
Indeks {a:1, b:1}
oznacza sort by a, then within each a, sort the b values
. Jeśli następnie wykonasz find({a:2}).sort({b:1})
, indeks wie, gdzie wszystkie a=2
są. W tym bloku a=2
, b
zostanie posortowane w porządku rosnącym (zgodnie ze specyfikacją indeksu), tak aby zapytanie find({a:2}).sort({b:1})
może być zaspokojony przez:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block forward to satisfy
2 | 2 <-- find({a:2}).sort({b:1})
2 | 3 <--
3 | 1
3 | 2
znajdź({a:2}).sortuj({b:-1})
Ponieważ indeks można chodzić do przodu lub do tyłu, zastosowano podobną procedurę, z małym skrętem na końcu:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block backward to satisfy
2 | 2 <-- find({a:2}).sort({b:-1})
2 | 3 <--
3 | 1
3 | 2
Fakt, że po indeksie można przejść do przodu lub do tyłu, jest kluczowym punktem, który umożliwia wykonanie zapytania find({a:2}).sort({b:-1})
aby móc korzystać z indeksu {a:1, b:1}
.
Wyjaśnienie dotyczące planowania zapytań
Możesz zobaczyć, co planuje planer zapytań, używając db.collection.explain().find(....)
. Zasadniczo, jeśli widzisz stage
z COLLSCAN
, nie użyto żadnego indeksu lub można go użyć w zapytaniu. Zobacz wyjaśnij wyniki
aby uzyskać szczegółowe informacje na temat wyników polecenia.