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


Manage indexing policies in Azure Cosmos DB (Управление политиками индексирования в Azure Cosmos DB)

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

Примечание.

Метод обновления политик индексирования, описанных в этой статье, применяется только к Azure Cosmos DB для NoSQL. Узнайте об индексировании в Azure Cosmos DB для MongoDB и вторичном индексировании в Azure Cosmos DB для Apache Cassandra.

Примеры политик индексирования

Ниже приведены некоторые примеры политик индексирования, отображаемых в формате JSON. Они предоставляются в портал Azure в формате JSON. Значения параметров можно задать с помощью Azure CLI или любого пакета SDK.

Политика отказа для выборочного исключения определённых путей к свойствам

{
    "indexingMode": "consistent",
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/path/to/single/excluded/property/?"
        },
        {
            "path": "/path/to/root/of/multiple/excluded/properties/*"
        }
    ]
}

Примечание.

  • Ключ раздела (если это не "/id") не индексируется и должен быть включен в индекс.
  • Идентификаторы системных свойств и _ts всегда индексируются, когда режим индексирования учетной записи Cosmos является согласованным.
  • Идентификаторы системных свойств id и _ts не включены в описание индексированных путей политики контейнера. Это связано с тем, что эти системные свойства индексируются по умолчанию, и это поведение не может быть отключено.

Политика согласия для выборочного включения некоторых путей к свойствам

{
    "indexingMode": "consistent",
    "includedPaths": [
        {
            "path": "/path/to/included/property/?"
        },
        {
            "path": "/path/to/root/of/multiple/included/properties/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/*"
        }
    ]
}

Примечание.

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

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

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?"
        }
    ],
    "spatialIndexes": [
        {
                    "path": "/path/to/geojson/property/?",
            "types": [
                "Point",
                "Polygon",
                "MultiPolygon",
                "LineString"
            ]
        }
    ]
}

Примеры политики индексирования векторов

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

Примечание.

Прежде чем продолжить, необходимо включить индексирование и поиск векторов NoSQL в Azure Cosmos DB.

Внимание

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

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?"
        },
        {
            "path": "/vector/*"
        }
    ],
    "vectorIndexes": [
        {
            "path": "/vector",
            "type": "quantizedFlat"
        }
    ]
}

Внимание

Векторный путь, добавленный в раздел "исключенные пути" политики индексирования, чтобы обеспечить оптимизированную производительность при вставке. Не добавляя векторный путь к "исключенным путям", это приведет к более высокой стоимости RU и задержкам для вставок векторов.

Внимание

В настоящее время политики векторов и векторные индексы неизменяемы после создания. Чтобы внести изменения, создайте новую коллекцию.

Можно определить следующие типы политик векторного индекса:

Тип Описание Максимальные размеры
flat Сохраняет векторы в том же индексе, что и другие индексированные свойства. 505
quantizedFlat Квантизует (сжимает) векторы перед хранением в индексе. Это может повысить задержку и пропускную способность за счет небольшого количества точности. 4096
diskANN Создает индекс на основе DiskANN для быстрого и эффективного поиска. 4096

flat-индексы и quantizedFlat-индексы используют индекс Azure Cosmos DB для хранения и чтения каждого вектора при выполнении векторного поиска. Поиск векторов с индексом flat осуществляется полным перебором и обеспечивает 100% точность. Однако существует ограничение 505 измерений для векторов на плоском индексе.

Индекс quantizedFlat сохраняет квантизованные или сжатые векторы в индексе. Векторный поиск с использованием quantizedFlat индекса также является поиском методом прямого перебора, однако его точность может быть немного меньше 100%, так как векторы квантуируются перед добавлением в индекс. Однако при поиске векторов с quantized flat задержка должна быть ниже, пропускная способность выше, а стоимость ЕЗ ниже, чем при векторных поисках по индексу flat. Это хороший вариант для сценариев, в которых вы используете фильтры запросов для сужения векторного поиска до относительно небольшого набора векторов.

Индекс diskANN — это отдельный индекс, определенный специально для векторов с использованием DiskANN, набора высокопроизводительных алгоритмов индексирования векторов, разработанных Microsoft Research. Индексы DiskANN могут предложить одну из самых низких задержек, наивысшее количество запросов в секунду (QPS) и запросы с наименьшей стоимостью РЕ, обеспечивая высокую точность. Однако, так как DiskANN является приблизительным ближайшим индексом соседей (ANN), точность может быть ниже quantizedFlat или flat.

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

  • quantizationByteSize: задает размер (в байтах) для квантизации продукта. Min=1, Default=dynamic (решение системы), Max=512. Установка этого параметра может привести к более высокой точности поиска векторов за счет более высоких затрат в RU и увеличения задержки. Это относится к обоим типам индексов quantizedFlat и DiskANN.
  • indexingSearchListSize: задает количество векторов для поиска во время построения индекса. Min=10, Default=100, Max=500. Установка этого большего размера может привести к более точному поиску векторов за счет более длительного времени сборки индекса и более высокой задержки приема векторов. Это относится только к DiskANN индексам.

Использование сегментированного diskANN

Сегментированная служба DiskANN помогает оптимизировать крупномасштабный векторный поиск, разделив индекс DiskANN на меньшие, более управляемые части. Указав VectorIndexShardKey в политике индексирования контейнера, можно создать несколько индексов DiskANN — по одному для каждого уникального значения выбранного свойства документа.

Такой подход может привести к более быстрому выполнению запросов, улучшению поиска и снижению затрат на RU, особенно при работе с данными с высокой кардинальностью. Независимо от того, создаете ли вы подсистемы рекомендаций, семантический поиск или интеллектуальные агенты, Sharded DiskANN обеспечивает больше контроля над структурой и выполнением индексирования векторов.

Здесь можно увидеть пример определения ключа сегментов на основе свойства tenantID. Это может быть любое свойство элемента данных, даже ключа раздела. Обратите внимание, что одна строка должна быть заключена в массив. Дополнительные сведения о сегментированной базе данных DiskANN.

"vectorIndexes": [
    {
        "path": "/vector2",
        "type": "DiskANN",
        "vectorIndexShardKey": ["/tenantID"]
    }
]

Примеры политики индексирования кортежей

В этом примере политика индексирования определяет индекс кортежа на events.name и events.category.

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {"path":"/*"}, 
        {"path":"/events/[]/{name,category}/?"} 
    ],
    "excludedPaths":[],
    "compositeIndexes":[]
}

Приведенный выше индекс используется для приведенного ниже запроса.

SELECT * 
FROM root r 
WHERE 
   EXISTS (SELECT VALUE 1 FROM ev IN r.events 
           WHERE ev.name = ‘M&M’ AND ev.category = ‘Candy’) 

Примеры политик составного индексирования

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

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

Примечание.

Составные пути имеют неявный подстановочный знак /?, так как в этих путях индексируется только скалярное значение. Подстановочный знак /* не поддерживается в составных путях. В составном пути не следует указывать /? и /*. Составные пути также чувствительны к регистру.

Составной индекс, определенный для (имя по возрастанию, возраст по убыванию)

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {  
                "path":"/name",
                "order":"ascending"
            },
            {  
                "path":"/age",
                "order":"descending"
            }
        ]
    ]
}

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

Запрос 1:

SELECT *
FROM c
ORDER BY c.name ASC, c.age DESC

Запрос 2:

SELECT *
FROM c
ORDER BY c.name DESC, c.age ASC

Этот составной индекс обеспечивает следующие запросы и оптимизирует фильтры:

Запрос 3:

SELECT *
FROM c
WHERE c.name = "Tim"
ORDER BY c.name DESC, c.age ASC

Запрос 4:

SELECT *
FROM c
WHERE c.name = "Tim" AND c.age > 18

Составной индекс, определенный для (имя ASC, возраст ASC) и (имя ASC, возраст DESC)

Можно определить несколько составных индексов в одной политике индексирования.

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {  
                "path":"/name",
                "order":"ascending"
            },
            {  
                "path":"/age",
                "order":"ascending"
            }
        ],
        [  
            {  
                "path":"/name",
                "order":"ascending"
            },
            {  
                "path":"/age",
                "order":"descending"
            }
        ]
    ]
}

Составной индекс, определенный для (имя ASC, возраст ASC)

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

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {  
               "path":"/name"
            },
            {  
               "path":"/age"
            }
        ]
    ]
}

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

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

{
    "indexingMode": "consistent",
    "includedPaths": [],
    "excludedPaths": [{
        "path": "/*"
    }]
}

Без индексирования

Эта политика отключает индексирование. Если indexingMode задано значение none, вы не можете задать TTL в контейнере.

{
    "indexingMode": "none"
}

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

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

  • На портале Azure
  • Использование Azure CLI
  • Использование PowerShell
  • Использование одного из пакетов SDK

Обновление политики индексирования активирует преобразование индекса. Ход выполнения этого преобразования можно отслеживать с помощью пакетов SDK.

Примечание.

При обновлении политики индексирования запись в Azure Cosmos DB не прерывается. Дополнительные сведения о преобразованиях индексирования.

Внимание

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

Использование портала Azure

Контейнеры Azure Cosmos DB хранят политику индексирования в виде документа JSON, который портал Azure позволяет напрямую редактировать.

  1. Войдите на портал Azure.

  2. Создайте новую учетную запись Azure Cosmos DB или выберите существующую учетную запись.

  3. Откройте область обозревателя данных и выберите контейнер, над которыми вы хотите работать.

  4. Выберите "Масштаб и параметры".

  5. Измените документ JSON политики индексирования, как показано в этих примерах.

  6. Нажмите кнопку "Сохранить " после завершения.

Управление индексированием с помощью портала Azure

Использование командной строки Azure CLI

Сведения о создании контейнера с настраиваемой политикой индексирования см. в статье "Создание контейнера с настраиваемой политикой индекса с помощью ИНТЕРФЕЙСА командной строки".

С помощью PowerShell

Сведения о создании контейнера с настраиваемой политикой индексирования см. в статье "Создание контейнера с настраиваемой политикой индекса с помощью PowerShell".

Использование пакета SDK для .NET

Объект ContainerProperties из пакета SDK для .NET версии 3 предоставляет IndexingPolicy свойство, которое позволяет изменять IndexingMode и добавлять или удалятьIncludedPaths.ExcludedPaths Дополнительные сведения см. в кратком руководстве: клиентская библиотека Azure Cosmos DB для NoSQL для .NET.

// Retrieve the container's details
ContainerResponse containerResponse = await client.GetContainer("database", "container").ReadContainerAsync();
// Set the indexing mode to consistent
containerResponse.Resource.IndexingPolicy.IndexingMode = IndexingMode.Consistent;
// Add an included path
containerResponse.Resource.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
// Add an excluded path
containerResponse.Resource.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/name/*" });
// Add a spatial index
SpatialPath spatialPath = new SpatialPath
{
    Path = "/locations/*"
};
spatialPath.SpatialTypes.Add(SpatialType.Point);
containerResponse.Resource.IndexingPolicy.SpatialIndexes.Add(spatialPath);
// Add a composite index
containerResponse.Resource.IndexingPolicy.CompositeIndexes.Add(new Collection<CompositePath> { new CompositePath() { Path = "/name", Order = CompositePathSortOrder.Ascending }, new CompositePath() { Path = "/age", Order = CompositePathSortOrder.Descending } });
// Update container with changes
await client.GetContainer("database", "container").ReplaceContainerAsync(containerResponse.Resource);

Чтобы отслеживать ход выполнения преобразования индекса, передайте объект RequestOptions, который задает для свойства PopulateQuotaInfo значение true. Получите значение из заголовка x-ms-documentdb-collection-index-transformation-progress ответа.

// retrieve the container's details
ContainerResponse containerResponse = await client.GetContainer("database", "container").ReadContainerAsync(new ContainerRequestOptions { PopulateQuotaInfo = true });
// retrieve the index transformation progress from the result
long indexTransformationProgress = long.Parse(containerResponse.Headers["x-ms-documentdb-collection-index-transformation-progress"]);

Fluent API SDK версии 3 позволяет написать это определение в краткой и эффективной форме при определении пользовательской политики индексирования при создании нового контейнера.

await client.GetDatabase("database").DefineContainer(name: "container", partitionKeyPath: "/myPartitionKey")
    .WithIndexingPolicy()
        .WithIncludedPaths()
            .Path("/*")
        .Attach()
        .WithExcludedPaths()
            .Path("/name/*")
        .Attach()
        .WithSpatialIndex()
            .Path("/locations/*", SpatialType.Point)
        .Attach()
        .WithCompositeIndex()
            .Path("/name", CompositePathSortOrder.Ascending)
            .Path("/age", CompositePathSortOrder.Descending)
        .Attach()
    .Attach()
    .CreateIfNotExistsAsync();

Использование пакета SDK для Java

Объект DocumentCollection из пакета SDK для Java предоставляет getIndexingPolicy() методы и setIndexingPolicy() методы. Объект IndexingPolicy, которым они управляют, позволяет изменить режим индексирования и добавить или удалить включенные и исключенные пути. Для получения дополнительной информации см. Краткое руководство: создание приложения Java для управления данными NoSQL в Azure Cosmos DB.

// Retrieve the container's details
Observable<ResourceResponse<DocumentCollection>> containerResponse = client.readCollection(String.format("/dbs/%s/colls/%s", "database", "container"), null);
containerResponse.subscribe(result -> {
DocumentCollection container = result.getResource();
IndexingPolicy indexingPolicy = container.getIndexingPolicy();

// Set the indexing mode to consistent
indexingPolicy.setIndexingMode(IndexingMode.Consistent);

// Add an included path

Collection<IncludedPath> includedPaths = new ArrayList<>();
IncludedPath includedPath = new IncludedPath();
includedPath.setPath("/*");
includedPaths.add(includedPath);
indexingPolicy.setIncludedPaths(includedPaths);

// Add an excluded path

Collection<ExcludedPath> excludedPaths = new ArrayList<>();
ExcludedPath excludedPath = new ExcludedPath();
excludedPath.setPath("/name/*");
excludedPaths.add(excludedPath);
indexingPolicy.setExcludedPaths(excludedPaths);

// Add a spatial index

Collection<SpatialSpec> spatialIndexes = new ArrayList<SpatialSpec>();
Collection<SpatialType> collectionOfSpatialTypes = new ArrayList<SpatialType>();

SpatialSpec spec = new SpatialSpec();
spec.setPath("/locations/*");
collectionOfSpatialTypes.add(SpatialType.Point);
spec.setSpatialTypes(collectionOfSpatialTypes);
spatialIndexes.add(spec);

indexingPolicy.setSpatialIndexes(spatialIndexes);

// Add a composite index

Collection<ArrayList<CompositePath>> compositeIndexes = new ArrayList<>();
ArrayList<CompositePath> compositePaths = new ArrayList<>();

CompositePath nameCompositePath = new CompositePath();
nameCompositePath.setPath("/name");
nameCompositePath.setOrder(CompositePathSortOrder.Ascending);

CompositePath ageCompositePath = new CompositePath();
ageCompositePath.setPath("/age");
ageCompositePath.setOrder(CompositePathSortOrder.Descending);

compositePaths.add(ageCompositePath);
compositePaths.add(nameCompositePath);

compositeIndexes.add(compositePaths);
indexingPolicy.setCompositeIndexes(compositeIndexes);

// Update the container with changes

 client.replaceCollection(container, null);
});

Чтобы отслеживать ход преобразования индекса в контейнере, передайте объект RequestOptions, который запрашивает сведения о квоте для заполнения. Получите значение из заголовка x-ms-documentdb-collection-index-transformation-progress ответа.

// set the RequestOptions object
RequestOptions requestOptions = new RequestOptions();
requestOptions.setPopulateQuotaInfo(true);
// retrieve the container's details
Observable<ResourceResponse<DocumentCollection>> containerResponse = client.readCollection(String.format("/dbs/%s/colls/%s", "database", "container"), requestOptions);
containerResponse.subscribe(result -> {
    // retrieve the index transformation progress from the response headers
    String indexTransformationProgress = result.getResponseHeaders().get("x-ms-documentdb-collection-index-transformation-progress");
});

Использование пакета SDK для Node.js

Интерфейс ContainerDefinition из пакета SDKNode.js предоставляет indexingPolicy свойство, которое позволяет изменять indexingMode, а также добавлять или удалять includedPaths и excludedPaths. Дополнительные сведения см. в кратком руководстве по клиентской библиотеке Azure Cosmos DB для NoSQL для Node.js.

Получение сведений о контейнере:

const containerResponse = await client.database('database').container('container').read();

Задайте для режима индексирования согласованность:

containerResponse.body.indexingPolicy.indexingMode = "consistent";

Добавьте включенный путь, включая пространственный индекс:

containerResponse.body.indexingPolicy.includedPaths.push({
    includedPaths: [
      {
        path: "/age/*",
        indexes: [
          {
            kind: cosmos.DocumentBase.IndexKind.Range,
            dataType: cosmos.DocumentBase.DataType.String
          },
          {
            kind: cosmos.DocumentBase.IndexKind.Range,
            dataType: cosmos.DocumentBase.DataType.Number
          }
        ]
      },
      {
        path: "/locations/*",
        indexes: [
          {
            kind: cosmos.DocumentBase.IndexKind.Spatial,
            dataType: cosmos.DocumentBase.DataType.Point
          }
        ]
      }
    ]
  });

Добавьте исключенный путь:

containerResponse.body.indexingPolicy.excludedPaths.push({ path: '/name/*' });

Обновите контейнер с изменениями:

const replaceResponse = await client.database('database').container('container').replace(containerResponse.body);

Чтобы мониторить ход выполнения преобразования индекса в контейнере, передайте объект RequestOptions, который устанавливает свойство populateQuotaInfo на true. Получите значение из заголовка x-ms-documentdb-collection-index-transformation-progress ответа.

// retrieve the container's details
const containerResponse = await client.database('database').container('container').read({
    populateQuotaInfo: true
});
// retrieve the index transformation progress from the response headers
const indexTransformationProgress = replaceResponse.headers['x-ms-documentdb-collection-index-transformation-progress'];

Добавьте составной индекс:

 console.log("create container with composite indexes");
  const containerDefWithCompositeIndexes = {
    id: "containerWithCompositeIndexingPolicy",
    indexingPolicy: {
      automatic: true,
      indexingMode: IndexingMode.consistent,
      includedPaths: [
        {
          path: "/*",
        },
      ],
      excludedPaths: [
        {
          path: '/"systemMetadata"/*',
        },
      ],
      compositeIndexes: [
        [
          { path: "/field", order: "ascending" },
          { path: "/key", order: "ascending" },
        ],
      ],
    },
  };
  const containerWithCompositeIndexes = (
    await database.containers.create(containerDefWithCompositeIndexes)
  ).container;

Использование Python SDK

При использовании пакета SDK для Python версии 3 конфигурация контейнера управляется как словарь. Из этого словаря вы можете получить доступ к политике индексирования и всем его атрибутам. Дополнительные сведения см. в кратком руководстве: клиентская библиотека Azure Cosmos DB для NoSQL для Python.

Получение сведений о контейнере:

containerPath = 'dbs/database/colls/collection'
container = client.ReadContainer(containerPath)

Задайте для режима индексирования согласованность:

container['indexingPolicy']['indexingMode'] = 'consistent'

Определите политику индексирования с включенным путем и пространственным индексом:

container["indexingPolicy"] = {

    "indexingMode":"consistent",
    "spatialIndexes":[
                {"path":"/location/*","types":["Point"]}
             ],
    "includedPaths":[{"path":"/age/*","indexes":[]}],
    "excludedPaths":[{"path":"/*"}]
}

Определите политику индексирования с исключенным путем:

container["indexingPolicy"] = {
    "indexingMode":"consistent",
    "includedPaths":[{"path":"/*","indexes":[]}],
    "excludedPaths":[{"path":"/name/*"}]
}

Добавьте составной индекс:

container['indexingPolicy']['compositeIndexes'] = [
                [
                    {
                        "path": "/name",
                        "order": "ascending"
                    },
                    {
                        "path": "/age",
                        "order": "descending"
                    }
                ]
                ]

Обновите контейнер с изменениями:

response = client.ReplaceContainer(containerPath, container)