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

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

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

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

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

Разве разреженный индекс не должен иметь дело с этим?

4 ответа

Решение

Разреженные индексы не содержат документов, которые пропускают индексированное поле. Однако, если поле существует и имеет значение null, он все еще будет проиндексирован. Итак, если отсутствует поле и его равенство null выглядят одинаково для вашего приложения, и вы хотите сохранить уникальность fbIdпросто не вставляйте его, пока у вас нет значения для него.

Вам нужны разреженные индексы, когда у вас есть большое количество документов, но только небольшая их часть содержит какое-то поле, и вы хотите иметь возможность быстрого поиска документов по этому полю. Создание обычного индекса было бы слишком дорого, вы бы просто тратили драгоценную оперативную память на индексацию документов, которые вас не интересуют.

Чтобы обеспечить максимальную производительность индексов, мы можем захотеть не индексировать документы, НЕ содержащие поле, по которому вы выполняете индекс. Для этого MongoDB имеет разреженное свойство, которое работает следующим образом:

db.addresses.ensureIndex( { "secondAddress": 1 }, { sparse: true } );

Этот индекс пропустит все документы, не содержащие поле secondAddress, и при выполнении запроса эти документы никогда не будут сканироваться.

Позвольте мне поделиться этой статьей об основных индексах и некоторых их свойствах:

Геопространственные, текстовые, хеш-индексы и уникальные и разреженные свойства: http://mongodbspain.com/en/2014/02/03/mongodb-indexes-part-2-geospatial-2d-2dsphere/


{a:1, b:5, c:2}
{a:8, b:15, c:7}
{a:4, b:7}
{a:3, b:10}

Предположим, что мы хотим создать индекс по вышеуказанным документам. Создание индекса на a & b не будет проблемой. Но что, если нам нужно создать индекс на c, Уникальное ограничение не будет работать для c ключи, потому что нулевое значение дублируется для 2 документов. Решение в этом случае заключается в использовании sparse вариант. Эта опция говорит базе данных не включать документы, которые пропускают ключ. Команда в концерне db.collectionName.createIndex({thing:1}, {unique:true, sparse:true}), Разреженный индекс позволяет нам использовать меньше места.

Обратите внимание, что даже если у нас есть sparse Индекс, база данных выполняет сканирование всех документов, особенно при выполнении сортировки. Это можно увидеть в разделе о выигрышном плане explainрезультат.

Разреженные индексы содержат только записи для документов, которые имеют индексированное поле, даже если поле индекса содержит нулевое значение. Индекс пропускает любой документ, в котором отсутствует индексированное поле. Индекс является «разреженным», поскольку он не включает все документы коллекции.

Другие вопросы по тегам