разреженные индексы и нулевые значения в монго - PullRequest
17 голосов
/ 22 декабря 2011

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

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

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

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

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

Ответы [ 3 ]

34 голосов
/ 22 декабря 2011

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

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

2 голосов
/ 03 сентября 2016

{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.

1 голос
/ 10 февраля 2014

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

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

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

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

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

...