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

Многоключови индекси на MongoDB и граници на пресичане на индекси

MongoDB има страхотна поддръжка за масиви и предоставя много гъвкавост в режима на вашия документ. Например, можете да вграждате масиви в документи и също така да вграждате документи в масиви и т.н. Въпреки това, работата с масиви има редица проблеми в MongoDB. В тази публикация ще разгледаме някои от проблемите, които MongoDB има с индексите и масивите.

Multikey индекси

В MongoDB можете да индексирате поле от масив, за да създадете индексен запис за всеки елемент в масива. Полученият индекс се нарича „multikey“ индекс. Многоключови индекси могат да бъдат създадени върху скаларни стойности или вградени документи. За повече информация относно многоключовите индекси вижте тази документация.

Индексите с няколко клавиша, макар и полезни, имат няколко ограничения:

  • Ако създадете комбиниран многоключов индекс, тогава имате най-много едно поле, което е масив.
  • Съставният индекс не може да бъде ключ на сегмент.
  • Съставният индекс не може да бъде хеширан индекс.
Ограничения на индекса с множество ключове на MongoDB – какво да внимавате при заявките си Щракнете за туит

Един от най-интересните аспекти на многоключовите индекси е как се изчисляват границите на пресичане на индексите.

Граници на пресичане на индекса

Ето как документацията на MongoDB дефинира границите на пресичане на индекса:

„Границите на сканирането на индекса определят частите от индекса за търсене по време на заявка. Когато съществуват множество предикати върху индекс, MongoDB ще се опита да комбинира границите за тези предикати чрез пресечна точка или смесване за да произведете сканиране с по-малки граници.”

Заявки за обхват на масиви

Нека започнем с прост пример, за да видим как MongoDB изчислява индексни граници за заявки към масиви. Да приемем, че имаме следните три документа в колекция:

{x:65}{x:35}{x:[12,95]}

Издаваме следната заявка:

db.coll.find({x :{ $gt :22, $lt:55})

Запитването е достатъчно просто. Очаквате отговорът да бъде {x:35}, но заявката връща:

{x:35}{x:[25,95]}

Причината идва от начина, по който MongoDB се справя с масивите. Не е необходимо един и същ елемент от масива да отговаря на двете условия; стига да има един елемент, отговарящ на всяко условие, той съответства. Така че в този случай границите са [22, Безкрайност] и [-Безкрайност, 55]. Тъй като оператор „elemMatch“ не се използва, MongoDB не използва пресечната точка на индекса. MongoDB не посочва кои от тези диапазони [22, Infinity] или [-Infinity, 55] ще бъдат използвани за изпълнението на заявката.

Ако искаме да използваме пресечната точка на индекса, тогава трябва да използваме следната заявка:

db.coll.find(x :{ $elemMatch:{$gt :22,$lt:55}})

Когато използвате това, MongoDB пресича границите на индекса и използва [22, 55] като граници. Както се очаква, тази заявка не връща никакви резултати (elemMatch не съответства на различни масиви). Така че по същество заявките за диапазон към масиви са доста безполезни без оператора $elemMatch.

Съставни многоключови индекси – смесване на масиви и полета без масив

Помислете за колекция със следните документи:

{артикул:35, цени:[250,35]}......{артикул:106, цени:[1500,65]}

Ще добавим сложен индекс към тази колекция:

db.ensureIndex({item:1, prices:1});

Сега нека изпълним проста заявка:

db. кол. find({item:{$gt:12, $lt:65}});

Заявката изглежда достатъчно проста, тъй като използваме елемент без масив с фиксиран диапазон. Очаквам границите на пресичане на индекса да бъдат нещо като item:[[12,65] ] за заявката, но ако стартирате обяснение, ще видите това:

"indexBounds" :{"item" :[ [ -Infinity, 65 ] ],"prices" :[ [ { "$minElement" :1 }, { "$maxElement" :1 } ] ]}, 

Причината е, че MongoDB открива, че това е многоключов индекс и не обработва пресечната точка на границите на индекса, независимо от факта, че вашата заявка не използва полета на масив. Моралът на историята е, че когато смесвате полета с масив и не-масив в индекс, винаги следете границите на пресичането на вашия индекс. Вероятно е, че не е ефикасно.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Създавайте, четете, актуализирайте, изтривайте данни с помощта на Node.js - Mongoose

  2. MongoDB група по вътрешни елементи на масива

  3. MongoDB не може да стартира сървър:Машината за съхранение по подразбиране 'wiredTiger' не е налична с тази версия на mongod

  4. Mongodb – Грешка при Mongoimport невалиден знак

  5. Mongo как да $търси с DBRef