Редкие индексы и нулевые значения в монго
Я не уверен, что правильно понимаю разреженные индексы.
У меня есть редкий уникальный индекс на fbId
{
"ns" : "mydb.users",
"key" : {
"fbId" : 1
},
"name" : "fbId_1",
"unique" : true,
"sparse" : true,
"background" : false,
"v" : 0
}
И я ожидал, что это позволит мне вставлять записи с нулевым значением в качестве fbId, но это вызывает дублирующее ключевое исключение. Это позволяет мне вставлять, если свойство fbId полностью удалено.
Не разрешен ли разреженный индекс?
Ответы
Ответ 1
Разреженные индексы не содержат документов, которые пропускают индексированное поле. Однако, если поле существует и имеет значение null
, оно все равно будет индексироваться. Итак, если отсутствие поля и его равенство null
выглядят одинаково для вашего приложения, и вы хотите сохранить уникальность fbId
, просто не вставляйте его, пока не получите его значение.
Вам нужны редкие индексы, когда у вас большое количество документов, но только небольшая часть из них содержит какое-то поле, и вы хотите быстро найти документы по этому полю. Создание нормального индекса было бы слишком дорого, вы просто потратили бы драгоценную RAM на индексирование документов, которые вам не интересны.
Ответ 2
Чтобы обеспечить максимальную производительность индексов, мы можем отказаться от индексирования тех документов, которые НЕ содержат поле, в котором вы выполняете индекс. Для этого MongoDB имеет разреженное свойство, которое работает следующим образом:
db.addresses.ensureIndex( { "secondAddress": 1 }, { sparse: true } );
Этот индекс будет опускать все документы, не содержащие поля secondAddress, и при выполнении запроса этот документ никогда не будет проверен.
Позвольте мне поделиться этой статьей об основных индексах и некоторых их свойствах:
Геопространственные, текстовые, индексы хеша и уникальные и разреженные свойства: http://mongodbspain.com/en/2014/02/03/mongodb-indexes-part-2-geospatial-2d-2dsphere/
Ответ 3
{a:1, b:5, c:2}
{a:8, b:15, c:7}
{a:4, b:7}
{a:3, b:10}
Предположим, что мы хотим создать индекс для вышеуказанных документов. Создание индекса на a
и b
не будет проблемой. Но что, если нам нужно создать индекс на c
. Уникальное ограничение не будет работать для ключей c
, поскольку значение null дублируется для двух документов. Решение в этом случае состоит в использовании опции sparse
. Этот параметр указывает базе данных не включать документы, пропускающие ключ. Вызывающая команда db.collectionName.createIndex({thing:1}, {unique:true, sparse:true})
. Редкий индекс позволяет нам использовать меньше места.
Обратите внимание, что даже если у нас есть индекс sparse
, база данных выполняет все проверки документов, особенно при сортировке. Это можно увидеть в разделе выигрышный план результата explain
.