Управление индексированием в API Azure Cosmos DB для MongoDB

ПРИМЕНИМО К: API Azure Cosmos DB для MongoDB

В API Azure Cosmos DB для MongoDB задействуются основные функции управления индексами Azure Cosmos DB. Эта статья посвящена добавлению индексов с помощью API Azure Cosmos DB для MongoDB. Вы также можете ознакомиться с обзором индексирования в Azure Cosmos DB (эти сведения относятся ко всем API).

Индексирование для сервера MongoDB версии 3.6 и более поздних версий

API Azure Cosmos DB для сервера MongoDB версии 3.6 + автоматически индексирует _id поле и ключ сегмента (только в сегментированных коллекциях). API автоматически обеспечивает уникальность _id поля для каждого ключа сегмента.

api для MongoDB ведет себя иначе, чем SQL api Azure Cosmos DB, который индексирует все поля по умолчанию.

Изменение политики индексирования

Для изменения политики индексирования рекомендуется использовать обозреватель данных на портале Azure. . В обозревателе данных можно добавить отдельные поля и индексы с подстановочными знаками из редактора политики индексирования:

Редактор политики индексирования

Примечание

Создавать составные индексы с помощью редактора политики индексирования в обозревателе данных нельзя.

Типы индексов

По одному полю

Индекс можно создать для любого отдельного поля. Порядок сортировки индекса по одному полю не имеет значения. Следующая команда создает уникальный индекс для поля name:

db.coll.createIndex({name:1})

Такой же индекс одного поля по полю name можно создать и на портале Azure:

Добавление индекса имени в редакторе политики индексирования

Один запрос использует несколько индексов по одному полю, где это возможно. Для одной коллекции можно создать до 500 однополей индексов.

Составные индексы (MongoDB Server версии 3.6 и более поздних)

В API для MongoDB составные индексы необходимы , если запросу требуется возможность сортировать по нескольким полям одновременно. Для запросов с несколькими фильтрами, которые не требуют сортировки, создайте несколько индексов отдельных полей вместо составного индекса, чтобы сэкономить затраты на индексирование.

Составной индекс или индекс одного поля для каждого поля составного индекса приведет к такой же производительности при фильтрации в запросах.

Примечание

Создавать составные индексы по вложенным свойствам или массивам нельзя.

Следующая команда создает составной индекс по полям name и age:

db.coll.createIndex({name:1,age:1})

Составные индексы можно использовать для эффективной сортировки по нескольким полям одновременно, как показано в следующем примере:

db.coll.find().sort({name:1,age:1})

Предыдущий составной индекс также можно использовать для эффективной сортировки в запросе с противоположным порядком сортировки по всем полям. Ниже приведен пример:

db.coll.find().sort({name:-1,age:-1})

Однако последовательность путей в составном индексе должна точно соответствовать запросу. Ниже приведен пример запроса, для которого требуется дополнительный составной индекс:

db.coll.find().sort({age:1,name:1})

Примечание

Составные индексы используются только в запросах, которые сортируют результаты. Для запросов с несколькими фильтрами, которые не требуют сортировки, следует создавать несколько индексов по одному полю.

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

Для индексирования содержимого, хранящегося в массивах, Azure Cosmos DB создает многоключевые индексы. При индексировании поля со значением массива Azure Cosmos DB автоматически индексирует каждый элемент этого массива.

Геопространственные индексы

Многие геопространственные операторы работают эффективнее с геопространственными индексами. В настоящее время API Azure Cosmos DB для MongoDB поддерживает индексы 2dsphere. Этот API пока не поддерживает индексы 2d.

Ниже приведен пример создания геопространственного индекса по полю location.

db.coll.createIndex({ location : "2dsphere" })

Текстовые индексы

API Azure Cosmos DB для MongoDB в настоящее время не поддерживает текстовые индексы. Для запросов текстового поиска по строкам следует использовать интеграцию Когнитивного поиска Azure с Azure Cosmos DB.

Индексы с подстановочными знаками

Для запросов к неизвестным полям можно использовать индексы с подстановочными знаками. Предположим, у вас есть коллекция, содержащая данные о семьях.

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

"children": [
   {
     "firstName": "Henriette Thaulow",
     "grade": "5"
   }
]

Вот еще один пример с несколько иным набором свойств в children:

"children": [
    {
     "familyName": "Merriam",
     "givenName": "Jesse",
     "pets": [
         { "givenName": "Goofy" },
         { "givenName": "Shadow" }
         ]
   },
   {
     "familyName": "Merriam",
     "givenName": "John",
   }
]

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

Создание индекса с подстановочными знаками

Следующая команда создает индекс с подстановочными знаками для всех свойств children:

db.coll.createIndex({"children.$**" : 1})

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

С использованием синтаксиса с подстановочными знаками можно создавать следующие типы индексов:

  • По одному полю
  • Геопространственные данные

Индексирование всех свойств

Вот как создать индекс с подстановочными знаками для всех полей:

db.coll.createIndex( { "$**" : 1 } )

Индексы с подстановочными знаками также можно создавать в обозревателе данных на портале Azure:

Добавление индекса с подстановочными знаками в редакторе политики индексирования

Примечание

Если вы только начинаете разработку, мы настоятельно рекомендуем начинать с создания индекса с подстановочными знаками для всех полей. Это упростит разработку и оптимизацию запросов.

В документах с множеством полей стоимость в единицах запросов (ЕЗ) для операций записи и обновления может быть высокой. Поэтому при наличии рабочей нагрузки с интенсивными операциями записи вместо использования индексов с подстановочными знаками следует индексировать пути по отдельности.

Ограничения

Индексы с подстановочными знаками не поддерживают ни один из следующих типов или свойств индексирования:

  • Составные
  • СРОК ЖИЗНИ
  • Уникальная идентификация

В отличие от MongoDB, в API Microsoft Azure Cosmos DB для MongoDB нельзя использовать индексы с подстановочными знаками для:

  • создания индекса с подстановочными знаками, содержащего несколько конкретных полей;

    db.coll.createIndex(
        { "$**" : 1 },
        { "wildcardProjection " :
            {
               "children.givenName" : 1,
               "children.grade" : 1
            }
        }
    )
    
  • создания индекса с подстановочными знаками, не содержащего несколько конкретных полей.

    db.coll.createIndex(
        { "$**" : 1 },
        { "wildcardProjection" :
            {
               "children.givenName" : 0,
               "children.grade" : 0
            }
        }
    )
    

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

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

Перечисленные ниже операции широко используются в учетных записях, обслуживающих протокол wire версии 4.0 и более ранних версий. Вы можете узнать больше о поддерживаемых индексах и индексируемых свойствах из этой статьи.

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

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

Важно!

Уникальные индексы можно создавать только в том случае, если коллекция пуста (не содержит документов).

Следующая команда создает уникальный индекс для поля student_id:

globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1 }, {unique:true} )
{
    "_t" : "CreateIndexesResponse",
    "ok" : 1,
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 4
}

Для сегментированных коллекций для создания уникального индекса необходимо указывать ключ сегмента (секции). Иными словами, все уникальные индексы для сегментированной коллекции — это составные индексы, где одно из полей является ключом раздела.

Следующие команды создают сегментированную коллекцию coll (ключ сегмента — university) с уникальным индексом для полей student_id и university:

globaldb:PRIMARY> db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
{
    "_t" : "ShardCollectionResponse",
    "ok" : 1,
    "collectionsharded" : "test.coll"
}
globaldb:PRIMARY> db.coll.createIndex( { "university" : 1, "student_id" : 1 }, {unique:true});
{
    "_t" : "CreateIndexesResponse",
    "ok" : 1,
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 3,
    "numIndexesAfter" : 4
}

Если в предыдущем примере опустить предложение "university":1, будет возвращена ошибка со следующим сообщением:

не удается создать уникальный индекс для {student_id: 1.0} с шаблоном ключа сегмента {university: 1.0}

Индексы срока жизни

Чтобы настроить истечение срока действия документов в определенной коллекции, необходимо создать индекс срока жизни (TTL). Индекс TTL — это индекс по полю _ts со значением expireAfterSeconds.

Пример:

globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})

Предыдущая команда удаляет все документы коллекции db.coll, которые не менялись последние 10 секунд.

Примечание

Поле _ts характерно для Azure Cosmos DB и недоступно из клиентов MongoDB. Это зарезервированное (системное) свойство, содержащее метку времени последнего изменения документа.

Отслеживание хода индексирования

Версия 3.6 и более поздние версии API Azure Cosmos DB для MongoDB поддерживают команду currentOp() для отслеживания хода индексирования в экземпляре базы данных. Эта команда возвращает документ, содержащий сведения о выполняемых операциях в экземпляре базы данных. Команда currentOpиспользуется для отслеживания всех выполняемых операций во встроенной среде MongoDB. В API Azure Cosmos DB для MongoDB эта команда поддерживает только отслеживание операций с индексами.

Вот несколько примеров, демонстрирующих использование команды currentOp для отслеживания хода индексирования.

  • Получение хода индексирования для коллекции:

    db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
    
  • Получение хода индексирования для всех коллекций в базе данных:

    db.currentOp({"command.$db": <databaseName>})
    
  • Получение хода индексирования для всех баз данных и коллекций в учетной записи Azure Cosmos:

    db.currentOp({"command.createIndexes": { $exists : true } })
    

Примеры выходных данных индексирования

В сведениях о ходе индексирования отображается процент выполнения текущей операции индексирования. Приведен пример выходного документа для различных этапов индексирования.

  • Для операции индексирования для коллекции "foo" и базы данных "bar", которая выполнена на 60 %, будет возвращены следующие выходные данные. В поле Inprog[0].progress.total в качестве целевого процента выполнения отображается значение 100.

    {
          "inprog" : [
          {
                  ………………...
                  "command" : {
                          "createIndexes" : foo
                          "indexes" :[ ],
                          "$db" : bar
                  },
                  "msg" : "Index Build (background) Index Build (background): 60 %",
                  "progress" : {
                          "done" : 60,
                          "total" : 100
                  },
                  …………..…..
          }
          ],
          "ok" : 1
    }
    
  • Если операция индексирования для коллекции "foo" и базы данных "bar" только началась, в выходном документе может отображаться 0 % выполнения, пока не будет достигнут минимальный уровень.

    {
          "inprog" : [
          {
                  ………………...
                  "command" : {
                          "createIndexes" : foo
                          "indexes" :[ ],
                          "$db" : bar
                  },
                  "msg" : "Index Build (background) Index Build (background): 0 %",
                  "progress" : {
                          "done" : 0,
                          "total" : 100
                  },
                  …………..…..
          }
          ],
         "ok" : 1
    }
    
  • При завершении текущей операции индексирования в выходных данных отображаются пустые операции inprog.

    {
        "inprog" : [],
        "ok" : 1
    }
    

Фоновое обновление индекса

Независимо от значения, указанного для свойства Background индекса, обновления индекса всегда выполняются в фоновом режиме. Поскольку обновления индекса потребляют единицы запросов (ЕЗ) с более низким приоритетом по сравнению с другими операциями базы данных, изменения индекса не будут приводить к простою операций записи, обновления или удаления.

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

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

Примечание

Вы можете отслеживать ход индексирования.

Команда ReIndex

Команда reIndex воссоздает все индексы в коллекции. В некоторых редких случаях производительность запросов или другие проблемы с индексами в коллекции можно устранить, выполнив reIndex команду. При возникновении проблем с индексированием рекомендуется повторно создать индексы с помощью reIndex команды.

Команду reIndex можно запустить с использованием следующего синтаксиса:

db.runCommand({ reIndex: <collection> })

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

db.runCommand({"customAction":"GetCollection",collection:<collection>, showIndexes:true})

Образец вывода:

{
        "database" : "myDB",
        "collection" : "myCollection",
        "provisionedThroughput" : 400,
        "indexes" : [
                {
                        "v" : 1,
                        "key" : {
                                "_id" : 1
                        },
                        "name" : "_id_",
                        "ns" : "myDB.myCollection",
                        "requiresReIndex" : true
                },
                {
                        "v" : 1,
                        "key" : {
                                "b.$**" : 1
                        },
                        "name" : "b.$**_1",
                        "ns" : "myDB.myCollection",
                        "requiresReIndex" : true
                }
        ],
        "ok" : 1
}

Если улучшит reIndex производительность запросов, рекуиресреиндекс будет иметь значение true. Если reIndex не повысит производительность запроса, это свойство будет пропущено.

Миграция коллекций с индексами

В настоящее время уникальные индексы можно создавать только в том случае, если коллекция не содержит документов. Распространенные средства миграции MongoDB пытаются создавать уникальные индексы после импорта данных. Чтобы обойти эту ошибку, вы можете вручную создать соответствующие коллекции и уникальные индексы вместо их автоматического создания в средстве миграции. (Для этого в mongorestore следует использовать флаг --noIndexRestore в командной строке.)

Индексирование для MongoDB версии 3.2

У учетных записей Azure Cosmos, совместимых с версией 3.2 протокола wire MongoDB, другой набор доступных функций индексирования и значений по умолчанию. Вы можете проверить версию своей учетной записи и выполнить обновление до версии 3.6.

Если вы используете версию 3.2, в этом разделе описаны ее основные отличия от версии 3.6 и более поздних.

Удаление индексов по умолчанию (версия 3.2)

В отличие от версии 3.6 и более поздних версий API Azure Cosmos DB для MongoDB, в версии 3.2 каждое свойство индексируется по умолчанию. Для удаления этих индексов по умолчанию для коллекции (coll) можно использовать следующую команду:

> db.coll.dropIndexes()
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }

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

Составные индексы (версия 3.2)

Составные индексы содержат ссылки на множество полей документа. Если требуется создать составной индекс, выполните обновление до версии 3.6 или 4.0.

Индексы с подстановочными знаками (версия 3.2)

Если вам требуется индекс с подстановочными знаками, выполните обновление до версии 3.6 или 4.0.

Дальнейшие действия