Du kan tänka på MongoDB enfältsindex som en array, med pekare till dokumentplatser. Till exempel, om du har en samling med (observera att sekvensen är avsiktligt ur funktion):
[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}
Enkelfältsindex
Om du nu gör det:
db.collection.createIndex({a:1})
Indexet ser ungefär ut så här:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Notera tre viktiga saker:
- Det är sorterat efter
astigande - Varje post pekar på platsen där de relevanta dokumenten finns
- Indexet registrerar bara värdena för
afält.bfältet finns inte alls i indexet
Så om du gör en fråga som:
db.collection.find().sort({a:1})
Allt den behöver göra är att gå indexet uppifrån och ned, hämta och mata ut dokumentet som posterna pekar på. Observera att du också kan gå indexet från botten, t.ex.:
db.collection.find().sort({a:-1})
och den enda skillnaden är att du går indexet baklänges.
Eftersom b inte finns i indexet alls, kan du inte använda indexet när du frågar något om b .
Sammansatt index
I ett sammansatt index, t.ex.:
db.collection.createIndex({a:1, b:1})
Det betyder att du vill sortera efter a först, sortera sedan efter b . Indexet skulle se ut så här:
[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
Observera att:
- Indexet är sorterat från
a - Inom varje
adu har en sorteradb - Du har 5 indexposter jämfört med bara tre i det föregående exemplet med ett fält
Med detta index kan du göra en fråga som:
db.collection.find({a:2}).sort({b:1})
Det kan lätt hitta var a:2 gå sedan indexet framåt. Med tanke på det indexet kan du inte göra :
db.collection.find().sort({b:1})
db.collection.find({b:1})
I båda frågorna kan du inte enkelt hitta b eftersom den är spridd över hela indexet (dvs inte i sammanhängande poster). Hur du än kan gör:
db.collection.find({a:2}).sort({b:-1})
eftersom du i princip kan hitta var a:2 är och gå b poster bakåt.
Redigera :förtydligande av @marcospgps fråga i kommentaren:
Möjligheten att använda indexet {a:1, b:1} för att tillfredsställa find({a:2}).sort({b:-1}) faktiskt vettigt om du ser det från en sorterad tabellsynpunkt. Till exempel indexet {a:1, b:1} kan ses som:
a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
find({a:2}).sort({b:1})
Indexet {a:1, b:1} betyder sort by a, then within each a, sort the b values . Om du sedan gör en find({a:2}).sort({b:1}) , indexet vet var alla a=2 är. Inom detta block av a=2 , b skulle sorteras i stigande ordning (enligt indexspecifikationen), så att frågan find({a:2}).sort({b:1}) kan tillfredsställas av:
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})
Eftersom indexet kan gå framåt eller bakåt, följdes en liknande procedur, med en liten vridning i slutet:
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 att indexet kan gå framåt eller bakåt är nyckeln som möjliggör frågan find({a:2}).sort({b:-1}) för att kunna använda indexet {a:1, b:1} .
Frågeplaneraren förklarar
Du kan se vad frågeplaneraren planerar genom att använda db.collection.explain().find(....) . I grund och botten om du ser en stage av COLLSCAN , inget index användes eller kan användas för frågan. Se förklara resultat
för detaljer om kommandots utdata.