Серия статей о MongoDB — легко справиться с проблемами индекса MongoDB, возникающими на собеседованиях.

MongoDB

  Индекс — это специальная структура данных, которая хранится в наборе данных, который легко просматривать и читать (индекс хранит значение определенного поля или набора полей).,И являетсяИспользуется структура B-дерева. Индексы могут значительно повысить эффективность запросов MongoDB.
  Если индекса нет, MongoDB должна выполнить полное сканирование коллекции, то есть просканировать каждый документ в коллекции и выбрать документы, соответствующие условиям запроса. MongoDB может использовать индекс для ограничения количества запрашиваемых документов, если во время запроса существует соответствующий индекс, особенно при работе с большими объемами данных, поэтомуВыбор правильного индекса имеет решающее значение.

Чтобы создать индекс, необходимо рассмотреть следующие вопросы:

  • Для каждого индекса требуется не менее 8 КБ пространства данных;
  • Добавление индексов оказывает некоторое влияние на производительность операций записи. Для коллекций с высокой скоростью записи индексы обходятся дорого, поскольку каждая вставка также должна обновлять любые индексы;
  • Индексы полезны для коллекций с высокой скоростью чтения и не повлияют на неиндексированные запросы;
  • Когда индекс находится в состоянии действия, каждый индекс будет занимать место на диске и в памяти, поэтому необходимо отслеживать и обнаруживать эту ситуацию.

Пределы индекса:

  • Длина имени индекса не может превышать 128 полей;
  • Составной индекс не может иметь более 32 свойств;
  • Каждая коллекция Collection не может превышать 64 индекса;
  • Различные типы индексов также имеют свои ограничения.

1. Управление индексами

1.1 Создание индекса

Для создания индекса используется метод createIndex() в следующем формате:

db.collection.createIndex(<key and index type specification>,<options>)

createIndex() принимает необязательные параметры, список необязательных параметров выглядит следующим образом:

Parameter Type Description
background Boolean Процесс индексирования блокирует другие операции с базой данных. Можно указать фон для создания индексов в фоновом режиме, то есть добавить необязательный параметр «фон». «фон» по умолчанию имеет значение false.
unique Boolean Является ли созданный индекс уникальным. Укажите значение true, чтобы создать уникальный индекс. Значение по умолчанию неверно.
name string Имя индекса. Если не указано, MongoDB генерирует имя индекса, объединяя имена полей индекса и порядок сортировки.
dropDups Boolean Версия 3.0+ устарела. Удалять ли повторяющиеся записи при создании уникального индекса, укажите true, чтобы создать уникальный индекс. Значение по умолчанию неверно.
sparse Boolean Индексация не включена для данных полей, которых нет в документе, этот параметр требует особого внимания.Если установлено значение true, документы, не содержащие соответствующее поле, не будут запрашиваться в индексируемом поле. Значение по умолчанию неверно.
expireAfterSeconds integer Укажите значение в секундах, завершите настройку TTL и задайте время жизни коллекции.
v index version Номер версии индекса. Версия индекса по умолчанию зависит от версии, в которой работал mongod при создании индекса.
weights document Значение веса индекса, значение от 1 до 99 999, указывает вес оценки этого индекса относительно других индексированных полей.
default_language string Для текстовой индексации этот параметр определяет список стоп-слов и правил для определения основы и токенизаторов. По умолчанию английский
language_override string Для текстовых индексов этот параметр указывает имя поля, которое должно быть включено в документ.Язык переопределяет язык по умолчанию, который по умолчанию равен языку.

1.2 Просмотр указателя

Просмотрите все индексы в коллекции в следующем формате:

db.collection.getIndexes()

1.3 удалить индекс

Удаление индекса в коллекции: Формат следующий:

db.collection.dropIndexes()   //删除所有索引
db.collection.dropIndex()    //删除指定的索引  

1.4 Имя индекса

Имя индекса по умолчанию — это ключ индекса и значение1 или -1 каждого ключа в индексе в форме имя_индекса+1/-1, например:

db.products.createIndex( { item: 1, quantity: -1 } )----索引名称为item_1_quantity_-1

Также можно указать имя индекса:

db.products.createIndex( { item: 1, quantity: -1 } , { name: "inventory" } )  ----索引名称为inventory

1.5 Просмотр процесса создания индекса и завершение создания индекса

метод Разобрать
db.currentOp() Посмотреть процесс создания индекса
db.killOp(opid) Завершить создание индекса, где -opid — идентификатор операции.

1.6 Использование индекса

форма Разобрать
$indexStats Получить информацию о доступе к индексу
explain() Возвращает ситуацию запроса: используйте метод db.collection.explain() или cursor.explain() в режиме executeStats, чтобы вернуть статистику о процессе запроса, включая используемые индексы, количество просканированных документов и время обработки запроса в миллисекундах. ).
Hint() Управляйте индексом, например, чтобы заставить MongoDB использовать определенный индекс для операций db.collection.find(), укажите индекс с помощью метода hint()

1.7 Метрики MongoDB

MongoDB предоставляет ряд метрик для использования индекса и операций, которые, возможно, необходимо учитывать при анализе использования индекса базы данных, а именно:

форма Разобрать
metrics.queryExecutor.scanned Общее количество элементов индекса, просканированных во время запроса и оценки плана запроса.
metrics.operation.scanAndOrder Общее количество запросов, возвращающих отсортированные числа, которые невозможно отсортировать с помощью индекса.
collStats.totalIndexSize Общий размер всех индексов. Параметр масштаба влияет на это значение. Если в индексе используется префиксное сжатие (которое используется WiredTiger по умолчанию), возвращаемый размер будет отражать сжатый размер любого такого индекса при расчете суммы.
collStats.indexSizes Указывает ключ и размер каждого существующего индекса в коллекции. Параметр масштаба влияет на это значение
dbStats.indexes Содержит подсчет общего количества индексов для всех коллекций в базе данных.
dbStats.indexSize Общий размер всех индексов, созданных в этой базе данных.

1.8 Фоновые операции индексации

  Создание индекса в плотной коллекции (близкой к максимальной емкости базы данных): по умолчанию создание индекса в плотной коллекции (близкой к максимальной емкости базы данных) предотвратит другие операции. При создании индекса для плотной коллекции (которая приближается к максимальной емкости базы данных), База данных, содержащая коллекцию, недоступна для операций чтения или записи, пока построение индекса не будет завершено. Любая операция, требующая блокировки чтения или записи во всех базах данных (например, listDatabases), будет ожидать завершения построения индекса, который не является фоновым процессом.

следовательноВы можете использовать свойство background, чтобы задать создание фонового индекса, операция выглядит следующим образом:

db.people.createIndex( { zipcode: 1 }, { background: true } )
默认情况下,在创建索引时,background为false,可以和其他属性进行组合使用:
db.people.createIndex( { zipcode: 1 }, { background: true, sparse: true } )

2. Тип индекса

2.1 Индексы отдельных полей

  MongoDB может создать индекс для любого поля.По умолчанию все коллекции создают индекс для поля _id.Индекс _id предназначен для предотвращения вставки клиентом документа Document с тем же значением поля _id, а индекс поля _id нельзя удалить.
  Используйте индекс _id в сегментированном кластере. Если поле _id не используется в качестве ключа сегмента, приложение должно обеспечить уникальность значения в поле _id, чтобы предотвратить ошибки. Обходной путь заключается в использовании стандартного автоматически сгенерированного ObjectId для полный .
  В значении общего индекса с одним полем «1» указывает индекс, который сортирует элементы в порядке возрастания, а «-1» указывает индекс, который сортирует элементы в порядке убывания. Следующее:

Создайте индекс для одного поля, например:

{
  "_id": ObjectId("570c04a4ad233577f97dc459"),
  "score": 1034,
  "location": { state: "NY", city: "New York" }
}
//创建单字段索引
 db.records.createIndex( { score: 1 } )
 //支持的查询  
db.records.find( { score: 2 } )
db.records.find( { score: { $gt: 10 } } )

Создайте индекс для полей во встроенном документе Document, пример выглядит следующим образом:

db.records.createIndex( { "location.state": 1 } )
//支持的查询 
db.records.find( { "location.state": "CA" } )
db.records.find( { "location.city": "Albany", "location.state": "NY" } )

Создайте индекс во встроенном документе Document, пример выглядит следующим образом:

db.records.createIndex( { location: 1 } )
//支持查询 
db.records.find( { location: { city: "New York", state: "NY" } } )

2.2 Составной индекс

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

  • MongoDB имеет ограничение в 32 поля для любого составного индекса;
  • Невозможно создать составной индекс с типом хэш-индекса. Если вы попытаетесь создать составной индекс, содержащий поле хэш-индекса, вы получите сообщение об ошибке;
  • Порядок, в котором создаются индексы полей для составных индексов, важен. Поскольку индексы хранят ссылки на поля в порядке сортировки по возрастанию (1) или по убыванию (-1), для индексов с одним полем порядок сортировки ключей не имеет значения, поскольку MongoDB может перемещаться по индексу в любом направлении. Однако для составных индексов порядок сортировки может определять, может ли индекс поддерживать операции сортировки;
  • Помимо поддержки запросов, соответствующих всем индексированным полям, составные индексы также могут поддерживать запросы, соответствующие префиксу индексированного поля.

Формат создания составного индекса:

db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )

Порядок сортировки, пример составного индекса из двух полей, index{userid: 1, score: -1}, сначала сортировка по значению userid, а затем сортировка по баллам на основе сортировки по userid. Как показано ниже:

Создайте составной индекс, например:

{
 "_id": ObjectId(...),
 "item": "Banana",
 "category": ["food", "produce", "grocery"],
 "location": "4th Street Store",
 "stock": 4,
 "type": "cases"
}
//创建复合索引
db.products.createIndex( { "item": 1, "stock": 1 } )
//支持的查询
db.products.find( { item: "Banana" } )
db.products.find( { item: "Banana", stock: { $gt: 5 } } )

Префиксный запрос в составном индексе, пример такой:

//创建复合索引
db.products.createIndex({ "item": 1, "location": 1, "stock": 1 })
//前缀为:{ item: 1 }与{ item: 1, location: 1 }
//支持前缀查询为   
 db.products.find( { item: "Banana" } )
 db.products.find( { item: "Banana", location: “beijing”} )
//不支持前缀查询,不会提高查询效率
//不包含前缀字段
 db.products.find( { location: “beijing”} )
 db.products.find( { stock: { $gt: 5 } )
 db.products.find( { location: “beijing”,stock: { $gt: 5 } )
 //不按照创建复合索引字段顺序的前缀查询
 db.products.find( { location: “beijing”,item: "Banana" },stock: { $gt: 5 } )

2.3 Многоключевой индекс

  MongoDB использует индекс с несколькими ключами для создания индекса для каждого элемента массива. Индекс с несколькими ключами можно построить на ключе, таком как строка, число или массив встроенных документов. Если поле индекса содержит массива, MongoDB автоматически определит, следует ли создать индекс с несколькими ключами; вам не нужно указывать тип с несколькими ключами вручную.Который создан:

db.coll.createIndex( { <field>: < 1 or -1 > } )

граница индекса
   При использовании индекса с несколькими ключами будет происходить расчет границы индекса (граница индекса — это диапазон, который индекс может искать в процессе запроса), и расчет должен следовать некоторым правилам. То есть, когда все поля в условиях нескольких запросов существуют в индексе, MongoDB будет использовать пересечение или объединение и т. д., чтобы определить границы этих условных полей индекса и, наконец, сгенерировать минимальный диапазон поиска. Можно разделить на ситуации:
1) Граница пересечения
  Граница пересечения — это логическое пересечение нескольких границ., для заданного поля массива предполагает, что запрос использует несколько полей условий массива и может использовать многоключевое индексирование.MongoDB будет пересекать границы многоключевого индекса, если условные поля объединяются с помощью $elemMatch, пример следующий:

//survey Collection中document有一个item字段和一个ratings数组字段
{ _id: 1, item: "ABC", ratings: [ 2, 9 ] } 
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }

//在ratings数组上创建多键索引: 
db.survey.createIndex({ratings:1})

//两种查询
db.survey.find({ratings:{$elemMatch:{$gte:3,$lte:6}}})  //(1)
db.survey.find( { ratings : { $gte: 3, $lte: 6 } } )  //(2)

  Условия запроса больше или равны 3 и меньше или равны 6В (1) $elemMatch используется для подключения условий запроса, которые будут генерировать оценки пересечения: [[3,6]. В (2) запросе, если $elemMatch не используется, пересечения не будет, пока выполняется какое-либо условие.

2).Граница Союза
  Границы объединения часто используются для определения границ многоключевых составных индексов., например: для комбинированного индекса {a:1,b:1} существует граница поля a: [3, +∞) и граница поля b: (-∞, 6], объединение результат этих двух оценок: {a: [[3, Infinity]], b: [[-Infinity, 6]]}.

  И если MongoDB не может объединить две границы, MongoDB принудит сканирование индекса, используя границы первого поля индекса, в данном случае: a: [[3, Infinity]].

3. Комбинированный индекс полей массива
  Поле индекса составного индекса представляет собой массив. Например, документ документа коллекции опросов содержит поле элемента и поле массива рейтингов. Пример выглядит следующим образом:

{ _id: 1, item: "ABC", ratings: [ 2, 9 ] } 
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }

//在item字段和ratings字段创建一个组合索引:
db.survey.createIndex( { item: 1, ratings: 1 } )

//查询条件索引包含的两个key
db.survey.find( { item: "XYZ", ratings: { $gte: 3 } } )

Обработать условия запроса отдельно:

item: "XYZ" -->  [ [ "XYZ", "XYZ" ] ];
ratings: { $gte: 3 } -->  [ [ 3, Infinity ] ].

MongoDB использует границы объединения для объединения этих двух границ:

{ item: [ [ "XYZ", "XYZ" ] ], ratings: [ [ 3, Infinity ] ] }  

4) Построить составной индекс на массиве встроенных документов document
  Если массив содержит документ встроенных документов и вы хотите создать индекс для включенного поля документа встроенного документа, вам необходимо использовать объявление индексазапятая","для разделения имен полей, например:

ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]

Имя поля оценки: ratings.score.

5) Смешивание объединения полей не массивного типа и полей массивного типа

{ _id: 1, item: "ABC", ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ] } 
{ _id: 2, item: "XYZ", ratings: [ { score: 5, by: "anon" }, { score: 7, by: "wv" } ] }

//在item和数组字段ratings.score和ratings.by上创建一个组合索引
db.survey2.createIndex( { "item": 1, "ratings.score": 1, "ratings.by": 1 } )

//查询
db.survey2.find( { item: "XYZ", "ratings.score": { $lte: 5 }, "ratings.by": "anon" } )

Условия запроса обрабатываются отдельно:

item: "XYZ"--> [ ["XYZ","XYZ"] ];
score: {$lte:5}--> [[-Infinity,5]];
by: "anon" -->["anon","anon"].

  MongoDB может комбинировать границу ключа элемента с одной из двух границ ratings.score и ratings.by, то есть оценка или граница индекса зависит от условий запроса и значения ключа индекса. MongoDB не может гарантировать, какие поля границ и элементов объединены. Но если вы хотитеОбъединение рейтингов ratings.score и ratings.by по границам,ноЗапрос должен использовать $elemMatch.

6) Объединение границ индексов полей массива
   границы объединенных индексных ключей внутри массива,

  • Ключ индекса должен иметь тот же путь к полю, за исключением имени поля,
  • При запросе он должен быть объявлен с использованием $elemMatch на пути
  • Для встроенных документов используйте пути, разделенные запятыми, например, a.b.c.d — это путь к полю d. Чтобы объединить границы ключей индекса в одном и том же массиве, необходимо использовать $elemMatch на пути a.b.c.

Например: создайте составной индекс по полям ratings.score и ratings.by:

db.survey2.createIndex( { "ratings.score": 1, "ratings.by": 1 } )

Поля ratings.score и ratings.by имеют одни и те же рейтинги путей. Следующий запрос с использованием $elemMatch требует, чтобы поле рейтингов содержало элемент, соответствующий обоим условиям:

db.survey2.find( { ratings: { $elemMatch: { score: { $lte: 5 }, by: "anon" } } } )

Условия запроса обрабатываются отдельно:

score: { $lte: 5 } --> [ -Infinity, 5 ];
by: "anon"--> [ "anon", "anon" ].

MongoDB может использовать границы объединения для объединения этих двух границ:

{ "ratings.score" : [ [ -Infinity, 5 ] ], "ratings.by" : [ [ "anon", "anon" ] ] }  

7). Существуют также запросы, которые не используют $elemMatch и используют $elemMatch для неполных путей. Для получения дополнительной информации см. 《Официальная документация - Границы индекса Multikey".


лимит:

  • Для составного индекса с несколькими ключами каждый индексированный документ может иметь не более одного индексированного поля, значением которого является массив. Если составной многоключевой индекс уже существует, это ограничение нельзя нарушить при вставке документа;
  • Индекс с несколькими ключами не может быть объявлен как индекс ключа сегмента;
  • Хэш-индексы не могут иметь мультиключевые индексы;
  • Покрывающие запросы не могут выполняться для индексов с несколькими ключами;
  • Когда запрос указывает массив в целом как точное совпадение, MongoDB может использовать многоключевой индекс для поиска первого элемента массива запроса, но не может использовать сканирование многоключевого индекса для поиска всего массива. Альтернативой является использование индекса с несколькими ключами для запроса первого элемента массива, а затем MongoDB снова выполняет сопоставление массива с отфильтрованным документом.

2.4 Полнотекстовый указатель (текстовый указатель)

  MongoDB предоставляетТип полнотекстового индекса, который поддерживает поиск строкового содержимого в коллекциях и создает индексы с возможностью полнотекстового поиска для строк и строковых массивов.. Эти полнотекстовые индексы не хранят стоп-слова, зависящие от языка (например, "the", "a", "or"), и не позволяют словам в коллекции документов сохранять только корневые слова. Создано следующим образом:

db.collection.createIndex( { key: "text",key:"text" ..... } )

И MongoDB предоставляет веса и способы создания подстановочных знаков. Метод запроса состоит из нескольких строк, разделенных пробелами, а в запросе на исключение используется «-» следующим образом:

db.collection.find({$text:{$search:"runoob add -cc"}})

Чтобы удалить полный индекс, вам нужноимя индексаПерейти кМетод db.collection.dropIndex(), а чтобы получить имена индексов, используйте метод db.collection.getIndexes().

   Вы также можете указать язык полнотекстового указателя,свойство default_languageуказанный во время создания, или используйтесвойство language_overrideПереопределите язык по умолчанию при создании документа следующим образом:

//指定不同的语言的方法:创建全文索引的时候使用default_language属性
db.collection.createIndex(
  { content : "text" },
  { default_language: "spanish" })
  
//使用language_override属性覆盖默认的语言
db.quotes.createIndex( { quote : "text" },
                   { language_override: "idioma" } )
                   
//默认的全文索引名称为context_text,users.comments.text,指定名称MyTextIndex
db.collection.createIndex(
   {
     content: "text",
     "users.comments": "text",
     "users.profiles": "text"
   },
   {
     name: "MyTextIndex"
   }
)

Веса
  Каждому полнотекстовому индексу можно назначить разную степень поиска, задав вес.По умолчанию вес равен 1. Для каждого проиндексированного поля в документе MongoDB умножает количество совпадений на вес и суммирует результаты. Используя эту сумму, MongoDB затем вычисляет оценку документа, например:

{
  _id: 1,
  content: "This morning I had a cup of coffee.",
  about: "beverage",
  keywords: [ "coffee" ]
}
{
  _id: 2,
  content: "Who doesn't like cake?",
  about: "food",
  keywords: [ "cake", "food", "dessert" ]
}

//通过db.blog.createIndex来指定weight权重
db.blog.createIndex(
   {
     content: "text",
     keywords: "text",
     about: "text"
   },
   {
     weights: {
       content: 10,
       keywords: 5
     },
     name: "TextIndex"
   }
 )

Вес контента равен 10, вес ключевых слов равен 5, а вес по умолчанию для about равен 1. Следовательно, можно сделать вывод, что частота запросов контента в 2 раза выше для ключевых слов, и в 10 раз выше для полей about.

Полнотекстовое индексирование с подстановочными знаками
  Спецификаторы подстановочных знаков ($**) также можно использовать при создании полнотекстовых индексов для нескольких полей.. Используя полнотекстовый индекс с подстановочными знаками, MongoDB будет содержать строковые данные для каждого документа в коллекции. Например:

db.collection.createIndex( { "$**": "text" } )

Полнокнижный индекс с подстановочными знаками — это полнокнижный индекс с несколькими полями. Таким образом, во время создания индекса конкретным полям можно присвоить веса, чтобы управлять ранжированием результатов.

ограничение

  • Один полнотекстовый индекс на коллекцию: коллекция имеет не более одного полнотекстового индекса,
  • Текстовый поиск и подсказки, вы не можете использовать hint(), если запрос содержит выражение запроса $text;
  • Текстовый индекс и сортировка, операция сортировки не может получить порядок сортировки из текстового индекса, даже для составных текстовых индексов, то есть операция сортировки не может использовать сортировку в текстовом индексе;
  • Составные индексы. Составные индексы могут включать комбинацию ключей текстового индекса и ключей индекса по возрастанию/убыванию. Однако эти составные индексы имеют следующие ограничения:
    1) Составные текстовые индексы не могут содержать какие-либо другие специальные типы индексов, такие как многоключевые или поля геопространственного индекса.
    2) Если составной текстовый индекс включает ключ, предшествующий ключу текстового индекса, при выполнении поиска $text предикат запроса должен включать условие совпадения на равенство для предшествующего ключа.
    3) При создании составного текстового индекса все ключи текстового индекса должны быть перечислены рядом в документе спецификации индекса.

2.5 Хэш-индекс

  Хэш-индекс использует хэш-функцию для вычисления хэша значения индексированного поля.Хэш-функция сворачивает встроенный документ и хеширует все значение, но не поддерживает индексы с несколькими ключами (т. е. массивы). Метод convertShardKeyToHashed() используется для генерации ключа хэш-индекса. Создано следующим образом:

db.collection.createIndex( { _id: "hashed" } )

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

3. Свойства индекса

Свойства индекса включают индексы TTL, уникальные индексы, частичные индексы, разреженные индексы и индексы с учетом регистра.

3.1 TTL-индексы

  TTL-индексявляется специальным индексом с одним полем, иТип полядолжно бытьтип даты или массив, содержащий типы дат, который MongoDB может использовать для автоматического удаления документов из коллекции через определенное время или в определенное время. Срок действия данных полезен для определенных типов информации, таких как данные о событиях, созданные компьютером, журналы и информация о сеансе, которые должны сохраняться в базе данных только в течение ограниченного времени.

Метод создания индекса TTL такой же, как и метод создания обычного индекса, за исключением того, что будет добавлен дополнительный атрибут expireAfterSeconds в следующем формате:

db.collection.createIndex( {key and index type specification},{ expireAfterSeconds: time})

пример:

db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )

Укажите срок действия
Сначала создайте индекс TTL для поля, содержащего значение типа даты BSON или массив объектов типа даты BSON, и укажите значение expireAfterSeconds, равное 0. Для каждого документа в коллекции установите для поля даты индекса значение, соответствующее дате документа. Время истечения. Пример операции выглядит следующим образом:
первый шаг:

db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

Шаг 2:

db.log_events.insert( {
   "expireAt": new Date('July 22, 2013 14:00:00'),
   "logEvent": 2,
   "logMessage": "Success!"
} )

Тип истечения срока действия данных:

  • Когда указанное время истечет, срок действия истекших пороговых данных истечет, и они будут удалены;
  • Если поле представляет собой массив и в индексе есть несколько значений даты, MongoDB использует наименьшее (то есть самое раннее) значение даты в массиве для вычисления порога истечения;
  • Если поле индекса в документе не является датой или массивом, содержащим значения дат, срок действия документа не истечет;
  • Если документ не содержит индексного поля, срок действия документа не истекает.

Специальные ограничения индекса TTL:

  • Индексы TTL — это индексы с одним полем. Составные индексы не поддерживают TTL и игнорируют параметр expireAfterSeconds;
  • Атрибут _id не поддерживает индексы TTL;
  • Невозможно создать индекс TTL для коллекции с ограничениями, поскольку MongoDB не может удалить документы из коллекции с ограничениями;
  • Метод createIndex() нельзя использовать для изменения значения expireAfterSeconds существующего индекса. Вместо этого используйте команду базы данных collMod в сочетании с флагом коллекции индексов. В противном случае, чтобы изменить значение параметра для существующего индекса, этот индекс необходимо сначала удалить и создать заново;
  • Если у поля уже есть индекс одного поля без TTL, вы не можете создать индекс TTL для того же поля, потому что разные типы индексов не могут быть созданы для одного и того же ключа. Чтобы изменить индекс с одним полем без TTL на индекс TTL, этот индекс необходимо сначала удалить и создать заново с параметром expireAfterSeconds.

3.2 Уникальные индексы

  уникальный индексЭто гарантирует, что индексированное поле не хранит повторяющихся значений, т. е. обеспечивает уникальность индексированного поля. По умолчанию MongoDB создает уникальный индекс для поля _id во время создания коллекции. Создано следующим образом:

db.collection.createIndex( <key and index type specification>, { unique: true } )

Как создать одно поле, пример такой:

db.members.createIndex( { "user_id": 1 }, { unique: true } )

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

//创建的索引且强制groupNumber,lastname和firstname值组合的唯一性。
db.members.createIndex( { groupNumber: 1, lastname: 1, firstname: 1 }, { unique: true } )

Уникальный многоключевой индекс:

{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] }

//创建索引:
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )

//插入数据:唯一索引允许将以下Document插入Collection中,因为索引强制执行a.loc和a.qty值组合的唯一性:
db.collection.insert( { _id: 2, a: [ { loc: "A" }, { qty: 5 } ] } )
db.collection.insert( { _id: 3, a: [ { loc: "A", qty: 10 } ] } )

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

  • Выполните db.collection.createIndex() на первичном сервере для набора реплик.
  • Вызов db.collection.createIndex() в mongos для сегментированного кластера

ПРИМЕЧАНИЕ. Подробный анализ см.

лимит:

  • Если коллекция уже содержит данные, которые превышают ограничение уникальности индекса (то есть есть повторяющиеся данные), MongoDB не может создать уникальный индекс для указанного поля индекса.
  • Невозможно создать уникальный индекс по хеш-индексу
  • Уникальное ограничение применяется к одному документу в коллекции. Поскольку ограничения применяются к документу с одним документом, для уникального индекса с несколькими ключами документ может иметь элементы массива, которые вызывают дублирование значений ключа индекса, если значение ключа индекса этого документа документа не дублирует ключ индекса. значение другого документа документа. В этом случае повторяющиеся записи индекса вставляются в индекс только один раз.
  • Уникальные индексы Sharded Collection могут быть только следующими:
    1). Индекс на шард-ключе
    2) Ключ сегмента представляет собой составной индекс с префиксом
    3) Индекс _id по умолчанию; однако, если поле _id не является ключом сегмента или префиксом ключа сегмента, индекс _id применяет ограничение уникальности только для каждого сегмента. Если поле _id не является ни ключом сегмента, ни префиксом ключа сегмента, MongoDB ожидает, что приложение обеспечит уникальность значения _id между сегментами.

3.3 Частичные индексы

  Частичный индекс для выполнения частичного поиска с использованием указанного выражения фильтра. Создано путем добавления свойства partialFilterExpression в метод db.collection.createIndex(). Выражение фильтра выглядит следующим образом:

  • Выражения равенства (например, файл:значение или использование оператора $eq)
  • $existsexpression
  • Выражения $gt, $gte, $lt, $lte
  • $typeexpression
  • $and

Примеры следующие:

//创建部分索引
db.restaurants.createIndex(
   { cuisine: 1, name: 1 },
   { partialFilterExpression: { rating: { $gt: 5 } } }
)
//查询情况分类
db.restaurants.find( { cuisine: "Italian", rating: { $gte: 8 } } )   //(1)
db.restaurants.find( { cuisine: "Italian", rating: { $lt: 8 } } )    //(2)
db.restaurants.find( { cuisine: "Italian" } )                        //(3)

в:

  • (1) Запрос:Условие запроса { $gte: 8 } и условие индекса { $gt: 5 } могут образовывать полный набор (Условие запроса является подмножеством условия индекса, то есть больше 5 может содержать больше или равно 8), вы можете использовать запрос частичного индекса.
  • (2) Запрос:Если условие не соответствует полному набору, MongoDB не будет использовать частичный индекс для запросов или операций сортировки.
  • (3) Запрос:запросынет выражения фильтра, и не будет использовать частичный индекс, поскольку для использования частичного индекса запрос должен включать выражение фильтра (или модифицированное выражение фильтра, задающее подмножество выражений фильтра) как часть условия запроса.

лимит:

  • Невозможно создать несколько локальных индексов только с помощью выражений фильтра;
  • Одновременное использование локальных и разреженных индексов невозможно;
  • Индекс _id не может использовать локальный индекс, а индекс ключа сегмента не может использовать локальный индекс;
  • Если указаны и ограничения partialFilterExpression, и ограничения уникальности, ограничения уникальности применяются только к документам, которые удовлетворяют выражению фильтра. Частичные индексы с уникальными ограничениями могут вставлять документы, которые не соответствуют уникальным ограничениям, если документ не соответствует критериям фильтра.

3.4 Разреженные индексы

   Разреженный индекс ищет только записи документов, содержащих поле индекса, пропускает документы, ключ индекса которых не существует, то есть разреженный индекс не будет искать документы, которые не содержат разреженный индекс. По умолчанию 2dsphere (версия 2), 2d, geoHaystack, полнотекстовые индексы и т. д. всегда являются разреженными индексами. Метод создания db.collection.createIndex() добавляет разреженный атрибут следующим образом:

db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )

Когда разреженные индексы не используются:Если разреженный индекс приведет к неполному результирующему набору для запросов и операций сортировки, MongoDB не будет использовать индекс, если только в hint() индекс не указан явно.

Разреженный составной индекс:

  • Для разреженных составных индексов с упорядочением по возрастанию/убыванию, пока ключевой индекс в составном индексе существует, он будет обнаружен.
  • Для разреженного составного индекса с упорядочением по возрастанию/убыванию с геопространственными возможными данными может быть обнаружено только наличие геопространственного ключа.
  • Для разреженного составного индекса, содержащего восходящий/нисходящий полнотекстовый индекс, может быть обнаружено только наличие полнотекстового индекса.

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

Пример интеграции выглядит следующим образом:

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

//在score中创建稀疏索引: 
db.scores.createIndex( { score: 1 } , { sparse: true } )

//查询
db.scores.find( { score: { $lt: 90 } } )    //(1)
db.scores.find().sort( { score: -1 } )      //(2)
db.scores.find().sort( { score: -1 } ).hint( { score: 1 } ) //(3)

//在score字段上创建具有唯一约束和稀疏过滤器的索引:
db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )

//该索引允许插入具有score字段的唯一值的文档或不包括得分字段的文档。如下:
db.scores.insert( { "userid": "AAAAAAA", "score": 43 } )
db.scores.insert( { "userid": "BBBBBBB", "score": 34 } )
db.scores.insert( { "userid": "CCCCCCC" } )
db.scores.insert( { "userid": "DDDDDDD" } )

//索引不允许添加以下文档,因为已存在score值为82和90的文档
db.scores.insert( { "userid": "AAAAAAA", "score": 82 } )
db.scores.insert( { "userid": "BBBBBBB", "score": 90 } )

в:

  • (1) Запрос:Для возврата полного набора можно использовать запрос разреженного индекса:{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
  • (2) Запрос:MongoDB не будет выбирать разреженный индекс для завершения запроса, чтобы вернуть полные результаты, даже если сортировка выполняется по индексированным полям:
    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
    { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
  • (3) Запрос:Используйте hint(), чтобы вернуть желаемый полный набор:
    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

4. Прочие вопросы

4.1 Индексная стратегия

Индексная стратегия:

  • Оптимальный индекс для приложения должен учитывать множество факторов, в том числе тип ожидаемых запросов, соотношение операций чтения и записи и объем доступной в системе памяти.
  • При разработке стратегии индексации вы должны хорошо понимать запросы вашего приложения. Перед созданием индекса сопоставьте типы запросов, которые будут выполняться, чтобы можно было создавать индексы, ссылающиеся на эти поля. Индексы снижают производительность, но они более ценны для частых запросов к большим наборам данных. Подумайте об относительной частоте каждого запроса в вашем приложении и о том, оправдывает ли запрос индекс.
  • Наилучшей общей стратегией разработки индексов является анализ различных конфигураций индексов с использованием набора данных, аналогичного тому, который вы будете использовать в рабочей среде, чтобы увидеть, какие из них работают лучше всего. Проверьте текущие индексы, созданные для коллекции, чтобы убедиться, что они поддерживают ваши текущие и запланированные запросы. Если индекс больше не используется, удалите его.
  • Обычно MongoDB использует только один индекс для большинства запросов. Однако каждое предложение $ или запроса может использовать другой индекс, и, начиная с версии 2.6, MongoDB может использовать пересечение нескольких индексов.

4.2 Последующие действия

В последующем будет оптимизация индекса MongonDB, сводка по набору реплик и шардингу, и самое главное, будут суммированы некоторые ямки в реальном бою и реальный боевой процесс использования MongoDB.Вы можете обратить внимание на последующее обновление из серии MongoDB.

Наконец, вы можете обратить внимание на общедоступную учетную запись, учиться вместе, делиться галантереей каждый день и получать обучающее видео галантереи!