Поделиться через


Управление индексированием в Azure Cosmos DB для виртуального ядра MongoDB

Область применения: Виртуальные ядра MongoDB

Индексы — это структуры, которые повышают скорость извлечения данных, предоставляя быстрый доступ к полям в коллекции. Они работают путем создания упорядоченного набора указателей на данные, часто основанные на ключевых полях. Виртуальные ядра Azure Cosmos DB для MongoDB используют индексы в нескольких контекстах, включая отправку запросов, уникальные ограничения и сегментирование.

Внимание

Поле "_id" — это единственное поле, индексированное по умолчанию, и максимальный размер поля может быть2 KB. Рекомендуется добавить дополнительные индексы на основе фильтров запросов и предикатов для оптимизации производительности.

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

Для простоты рассмотрим пример приложения блога со следующей настройкой:

  • Имя базы данных: cosmicworks
  • Имя коллекции: products

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

{
  "_id": ObjectId("617a34e7a867530bff1b2346"),
  "title": "Azure Cosmos DB - A Game Changer",
  "content": "Azure Cosmos DB is a globally distributed, multi-model database service.",
  "author": {lastName: "Doe", firstName: "John"},
  "category": "Technology",
  "launchDate": ISODate("2024-06-24T10:08:20.000Z"),
  "published": true
}

Индексы с одним полем

Индексы одного поля хранят сведения из одного поля в коллекции. Порядок сортировки индекса одного поля не имеет значения. _id поле остается индексировано по умолчанию.

Azure Cosmos DB для виртуальных ядер MongoDB поддерживает создание индекса по следующим причинам.

  • Поля документа верхнего уровня.
  • Внедренный документ.
  • Поля в внедренных документах.

Следующая команда создает индекс одного поля в поле author , а следующая команда создает его в внедренном поле firstName.

use cosmicworks

db.products.createIndex({"author": 1})

// indexing embedded property
db.products.createIndex({"author.firstName": -1})

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

Примечание.

Azure Cosmos DB для виртуальных ядер MongoDB позволяет создавать не более 64 индексов в коллекции. В зависимости от уровня можно запланировать расширение до 300 индексов по запросу.

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

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

Следующая команда создает составной индекс в полях author и launchDate в противоположном порядке сортировки.

use cosmicworks

db.products.createIndex({"author":1, "launchDate":-1})

Order поля влияют на выборку или использование индекса. Запрос find не будет использовать созданный индекс.

use cosmicworks

db.products.find({"launchDate": {$gt: ISODate("2024-06-01T00:00:00.000Z")}})

Ограничения

  • Не более 32 полей\путей в составном индексе.

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

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

use cosmicworks

db.products.createIndex (
   { "author": 1, "launchDate": 1 },
   { partialFilterExpression: { "launchDate": { $gt: ISODate("2024-06-24T10:08:20.000Z") } } }
)

Ограничения

  • Частичные индексы не поддерживаются или UNIQUE не поддерживаютсяORDER BY, если фильтр не квалифисируется.

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

Текстовые индексы — это специальные структуры данных, которые оптимизируют текстовые запросы, что делает их более быстрыми и эффективными.

createIndex Используйте метод с параметром text для создания текстового индекса в title поле.

use cosmicworks;

db.products.createIndex({ title: "text" })

Примечание.

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

Настройка параметров текстового индекса

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

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

    use cosmicworks
    
    db.products.createIndex(
        { title: "text", content: "text" },
        { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false }
    )
    

Примечание.

Когда клиент выполняет текстовый поисковый запрос с термином Cosmos DB, оценка каждого документа в коллекции будет вычисляться на основе присутствия и частоты термина в полях "title" и "content", с более высоким значением поля "title" из-за его более высокого веса.

Выполнение поиска текста с помощью текстового индекса

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

  • Выполните поиск текста для фразы Cosmos DB.

    use cosmicworks
    
    db.products.find(
      { $text: { $search: "Cosmos DB" } }
    )
    
  • При необходимости используйте $meta оператор проекции вместе с textScore полем в запросе, чтобы просмотреть вес

    use cosmicworks
    
    db.products.find(
    { $text: { $search: "Cosmos DB" } },
    { score: { $meta: "textScore" } }
    )
    

Ограничения

  • В коллекции можно определить только один текстовый индекс.
  • Индексы текста поддерживают простой поиск текста и пока не предоставляют расширенные возможности поиска, такие как регулярные выражения.
  • Операции сортировки не могут использовать упорядочение текстового индекса в MongoDB.
  • Hint() не поддерживается в сочетании с запросом с помощью выражения $text.
  • Текстовые индексы могут быть относительно большими, потребляя значительное место в хранилище по сравнению с другими типами индексов.

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

Индекс по одному полю индексирует все пути под field ним, за исключением других полей, которые находятся на одном уровне. Например, для следующего примера документа

{
 "children":
    {
     "familyName": "Merriam",
     "pets": { "details": {“name”: "Goofy", ”age”: 3} }
   } 
}

Создание индекса на { "pets.$**": 1 }, создает индекс для свойств сведений и поддокументов, но не создает индекс на "familyName".

Ограничения

  • Индексы подстановочных знаков не могут поддерживать уникальные индексы.
  • Индексы подстановочных ORDER BY знаков не поддерживают отложений, если фильтр не содержит только пути, присутствующих в подстановочных знаках (так как они не индексируют неопределенные элементы)
  • Составной индекс подстановочного знака может иметь one только подстановочный знак и one более термины индекса. { "pets.$**": 1, “familyName”: 1 }

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

Геопространственные индексы поддерживают запросы к данным, хранящимся в виде объектов GeoJSON или устаревших пар координат. Геопространственные индексы можно использовать для повышения производительности запросов на геопространственные данные или для выполнения определенных геопространственных запросов.

Виртуальные ядра Azure Cosmos DB для MongoDB предоставляют два типа геопространственных индексов:

  • 2dsphere Indexes, поддерживающие запросы, которые интерпретируют геометрию в сфере.
  • 2d Indexes, поддерживающие запросы, которые интерпретируют геометрию на плоской поверхности.

2d-индексы

2d индексы поддерживаются только с устаревшим стилем пары координат хранения геопространственных данных.

createIndex Используйте метод с параметром 2d для создания геопространственного индекса в location поле.

db.places.createIndex({ "location": "2d"});

Ограничения

  • Только one поле расположения может быть частью 2d индекса, а только one другое не геопространственного поля может быть частью compound 2d индекса. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })

2dsphere indexes

2dsphere индексы поддерживают геопространственные запросы на земной шаре. Он может поддерживать оба объекта GeoJSON или устаревшие пары координат. 2dSphere индексы работают со стилем GeoJSON хранения данных, если обнаружены устаревшие точки, то он преобразуется в точку GeoJSON.

createIndex Используйте метод с параметром 2dsphere для создания геопространственного индекса в location поле.

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

2dsphere индексы позволяют создавать индексы в нескольких геопространственных и нескольких полях данных, отличных от геопространственных. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })

Ограничения

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

    // Compound Regular & 2dsphere indexes are not supported yet
    db.collection.createIndex({a: 1, b: "2dsphere"})
    
    // Compound 2d indexes are not supported yet
    db.collection.createIndex({a: "2d", b: 1})
    
  • Многоугольники с отверстиями не работают. Вставка многоугольника с отверстием не ограничена, хотя $geoWithin запрос завершается сбоем для сценариев:

    1. Если сам запрос имеет многоугольник с отверстиями

      coll.find(
        {
            "b": {
                "$geoWithin": {
                    "$geometry": {
                        "coordinates": [
                            [
                                [ 0, 0], [0, 10], [10, 10],[10,0],[0, 0]
                            ],
                            [
                                [5, 5], [8, 5], [ 8, 8], [ 5, 8], [ 5, 5]
                            ]
                        ],
                        "type": "Polygon"
                    }
                }
            }
        })
      
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    2. Если есть нефильтрованный документ с многоугольником с отверстиями.

      [mongos] test> coll.find()
        [
          {
            _id: ObjectId("667bf7560b4f1a5a5d71effa"),
            b: {
              type: 'Polygon',
              coordinates: [
                [ [ 0, 0 ], [ 0, 10 ], [ 10, 10 ], [ 10, 0 ], [ 0, 0 ] ],
                [ [ 5, 5 ], [ 8, 5 ], [ 8, 8 ], [ 5, 8 ], [ 5, 5 ] ]
              ]
            }
          }
        ]
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    3. key поле является обязательным при использовании geoNear.

       [mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }])
      
       // MongoServerError: $geoNear requires a 'key' option as a String
      

Следующие шаги