MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Съставни индекси на MongoDB - има ли значение редът на сортиране?

Можете да мислите за 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 , не е използван индекс или може да се използва за заявката. Вижте обяснени резултати за подробности относно изхода на командата.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Добавяне на BSON масив към MongoDB 3.2 документ и извличане на стойностите обратно ( MongoCXX 3.2 ) ( C++ 11)

  2. Как да форматирате данни за MongoEngine PointField

  3. Премахване на обект с ObjectId от масив в Mongoose/MongoDB

  4. MongoDB/NoSQL:Поддържане на историята на промените в документа

  5. MongoDB в PHP, използващ агрегат за групиране по _id е null не работи