Подтвердить что ты не робот

Редкие индексы и нулевые значения в монго

Я не уверен, что правильно понимаю разреженные индексы.

У меня есть редкий уникальный индекс на fbId

{
    "ns" : "mydb.users",
    "key" : {
        "fbId" : 1
    },
    "name" : "fbId_1",
    "unique" : true,
    "sparse" : true,
    "background" : false,
    "v" : 0
}

И я ожидал, что это позволит мне вставлять записи с нулевым значением в качестве fbId, но это вызывает дублирующее ключевое исключение. Это позволяет мне вставлять, если свойство fbId полностью удалено.

Не разрешен ли разреженный индекс?

4b9b3361

Ответ 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.