Du kan tænke på MongoDB enkeltfeltsindeks som et array med pointere til dokumentplaceringer. For eksempel, hvis du har en samling med (bemærk, at sekvensen bevidst er ude af rækkefølge):
[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}
Enkeltfeltsindeks
Hvis du nu gør det:
db.collection.createIndex({a:1})
Indekset ser omtrent sådan ud:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Bemærk tre vigtige ting:
- Det er sorteret efter
astigende - Hver indtastning peger på det sted, hvor de relevante dokumenter ligger
- Indekset registrerer kun værdierne af
aMark.bfelt findes slet ikke i indekset
Så hvis du laver en forespørgsel som:
db.collection.find().sort({a:1})
Alt det skal gøre er at gå indekset fra top til bund, hente og udskrive det dokument, som indtastningerne peger på. Bemærk, at du også kan gå i indekset fra bunden, f.eks.:
db.collection.find().sort({a:-1})
og den eneste forskel er, at du går indekset omvendt.
Fordi b er slet ikke i indekset, kan du ikke bruge indekset, når du forespørger noget om b .
Sammensat indeks
I et sammensat indeks f.eks.:
db.collection.createIndex({a:1, b:1})
Det betyder, at du vil sortere efter a først, sorter derefter efter b . Indekset ville se sådan ud:
[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
Bemærk at:
- Indekset er sorteret fra
a - Inden for hver
adu har en sorteretb - Du har 5 indeksindgange i forhold til kun tre i det foregående enkeltfeltseksempel
Ved at bruge dette indeks kan du lave en forespørgsel som:
db.collection.find({a:2}).sort({b:1})
Det kan nemt finde hvor a:2 gå derefter indekset frem. I betragtning af det indeks kan du ikke gøre det :
db.collection.find().sort({b:1})
db.collection.find({b:1})
I begge forespørgsler kan du ikke nemt finde b da det er spredt over hele indekset (dvs. ikke i sammenhængende poster). Men du kan gør:
db.collection.find({a:2}).sort({b:-1})
da du i det væsentlige kan finde hvor a:2 er, og gå b indtastninger baglæns.
Rediger :præcisering af @marcospgps spørgsmål i kommentaren:
Muligheden for at bruge indekset {a:1, b:1} for at tilfredsstille find({a:2}).sort({b:-1}) giver faktisk mening, hvis du ser det fra et sorteret bordsynspunkt. For eksempel indekset {a:1, b:1} kan opfattes som:
a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
find({a:2}).sort({b:1})
Indekset {a:1, b:1} betyder sort by a, then within each a, sort the b values . Hvis du derefter laver en find({a:2}).sort({b:1}) , indekset ved, hvor alle a=2 er. Inden for denne blok af a=2 , b ville blive sorteret i stigende rækkefølge (i henhold til indeksspecifikationen), så forespørgslen find({a:2}).sort({b:1}) kan tilfredsstilles ved:
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
find({a:2}).sort({b:-1})
Da indekset kan gås frem eller tilbage, blev en lignende procedure fulgt, med en lille drejning i slutningen:
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
Det faktum, at indekset kan gås frem eller tilbage, er nøglepunktet, der aktiverer forespørgslen find({a:2}).sort({b:-1}) for at kunne bruge indekset {a:1, b:1} .
Forklaring af forespørgselsplanlægning
Du kan se, hvad forespørgselsplanlæggeren planlægger ved at bruge db.collection.explain().find(....) . Grundlæggende hvis du ser et stage af COLLSCAN , intet indeks blev brugt eller kan bruges til forespørgslen. Se forklar resultater
for detaljer om kommandoens output.