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


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

ОБЛАСТЬ ПРИМЕНЕНИЯ: NoSQL

В 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/*"
        }
    ]
}

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

{
    "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"
        }
    ]
}

Внимание

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

Внимание

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

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

Тип Описание Максимальное количество измерений
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.

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

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

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

В этом примере политика индексирования определяет индекс кортежа на events.name и событиях.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 предложение для нескольких свойств, для этих свойств требуется составной индекс . Если запрос включает фильтры вместе с сортировкой по нескольким свойствам, может потребоваться несколько составных индексов.

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

Примечание.

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

Составной индекс, определенный для (name asc, age desc)

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

Составной индекс, определенный для (name ASC, age ASC) и (name ASC, age 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"
            }
        ]
    ]
}

Составной индекс, определенный для (name ASC, age 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"]);

Api 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 для управления данными Azure Cosmos DB для NoSQL.

// 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 из пакета SDK Node.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)

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

Дополнительные сведения об индексировании см. по следующим ссылкам: