Можете да мислите за MongoDB индекс с едно поле като масив с указатели към местоположения на документи. Например, ако имате колекция с (обърнете внимание, че последователността умишлено не е в ред):
[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}
Индекс с едно поле
Сега, ако го направите:
db.collection.createIndex({a:1})
Индексът изглежда приблизително така:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Обърнете внимание на три важни неща:
- Сортиран е по
a
възходящо - Всеки вход сочи към мястото, където се намират съответните документи
- Индексът записва само стойностите на
a
поле.b
полето изобщо не съществува в индекса
Така че, ако направите заявка като:
db.collection.find().sort({a:1})
Всичко, което трябва да направи, е да премине през индекса отгоре надолу, като извлече и изведе документа, към който сочат записите. Забележете, че можете също да вървите по индекса отдолу, напр.:
db.collection.find().sort({a:-1})
и единствената разлика е, че вървите по индекса наобратно.
Защото b
изобщо не е в индекса, не можете да използвате индекса, когато правите заявки за b
.
Съставен индекс
В съставен индекс, напр.:
db.collection.createIndex({a:1, b:1})
Това означава, че искате да сортирате по a
първо, след това сортирайте по b
. Индексът ще изглежда така:
[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
Имайте предвид, че:
- Индексът е сортиран от
a
- Във всеки
a
имате сортиранb
- Имате 5 записа в индекс срещу само три в предишния пример с едно поле
Използвайки този индекс, можете да направите заявка като:
db.collection.find({a:2}).sort({b:1})
Може лесно да намери къде a:2
след това вървете с индекса напред. При този индекс не можете да направите :
db.collection.find().sort({b:1})
db.collection.find({b:1})
И в двете заявки не можете лесно да намерите b
тъй като е разпръснат из целия индекс (т.е. не в съседни записи). Въпреки това виеможете направи:
db.collection.find({a:2}).sort({b:-1})
тъй като по същество можете да намерите къде a:2
са и вървете по b
записи назад.
Редактиране :пояснение на въпроса на @marcospgp в коментара:
Възможността за използване на индекс {a:1, b:1}
за да удовлетворите find({a:2}).sort({b:-1})
всъщност има смисъл, ако го видите от гледна точка на сортирана таблица. Например индексът {a:1, b:1}
може да се разглежда като:
a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
find({a:2}).sort({b:1})
Индексът {a:1, b:1}
означава sort by a, then within each a, sort the b values
. Ако след това направите find({a:2}).sort({b:1})
, индексът знае къде всички a=2
са. В рамките на този блок от a=2
, b
ще бъдат сортирани във възходящ ред (според спецификацията на индекса), така че заявката find({a:2}).sort({b:1})
може да бъде удовлетворен от:
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})
Тъй като индексът може да се движи напред или назад, беше последвана подобна процедура, с малък обрат в края:
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
Фактът, че индексът може да се движи напред или назад, е ключовият момент, който позволява заявката find({a:2}).sort({b:-1})
за да можете да използвате индекса {a:1, b:1}
.
Обяснение на инструмента за планиране на заявки
Можете да видите какво планира програмата за планиране на заявки, като използвате db.collection.explain().find(....)
. По принцип, ако видите stage
на COLLSCAN
, не е използван индекс или може да се използва за заявката. Вижте обяснени резултати
за подробности относно изхода на командата.