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


Обновление или перестроение индекса в службе "Поиск ИИ Azure"

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

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

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

Обновление содержимого

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

Текст запроса содержит один или несколько документов для индексирования. В запросе каждый документ в индексе:

  • Определяется уникальным ключом с учетом регистра.
  • Связанное с действием: "upload", "delete", "merge" или "mergeOrUpload".
  • Заполнено набором пар "имя-значение" для каждого поля, добавляемого или обновляемого.
{  
  "value": [  
    {  
      "@search.action": "upload (default) | merge | mergeOrUpload | delete",  
      "key_field_name": "unique_key_of_document", (key/value pair for key field from index schema)  
      "field_name": field_value (name/value pairs matching index schema)  
        ...  
    },  
    ...  
  ]  
}
  • Во-первых, используйте API-интерфейсы для загрузки документов, таких как документы — индекс (REST) или эквивалентный API в пакетах SDK Azure. Дополнительные сведения о методах индексирования см. в разделе "Загрузка документов".

  • Для большого обновления рекомендуется пакетирование (до 1000 документов на пакет или около 16 МБ на пакет, в зависимости от того, какой предел приходится первым) и значительно повышает производительность индексирования.

  • @search.action Задайте параметр в API, чтобы определить влияние на существующие документы.

    Действие Эффект
    удалить Удаляет весь документ из индекса. Если вы хотите удалить отдельное поле, вместо этого используйте merge, указав для нужного поля значение NULL. Удаленные документы и поля не сразу освобождают место в индексе. Каждые несколько минут фоновый процесс выполняет физическое удаление. Независимо от того, используется ли портал Azure или API для возврата статистики индексов, вы можете ожидать небольшую задержку, прежде чем удаление будет отражено на портале Azure и через API.
    объединить Обновляет документ, который уже существует, и не удается найти документ. Слияние заменяет существующие значения. По этой причине обязательно проверьте поля коллекции, содержащие несколько значений, таких как поля типа Collection(Edm.String). Например, если tags поле начинается со значения ["budget"] и выполняется слияние с ["economy", "pool"], конечное значение tags поля равно ["economy", "pool"]. Это не будет ["budget", "economy", "pool"].

    Такое же поведение применяется к сложным коллекциям. Если документ содержит сложное поле коллекции с именем "Комнаты" со значением [{ "Type": "Budget Room", "BaseRate": 75.0 }], и выполняется слияние со значением [{ "Type": "Standard Room" }, { "Type": "Budget Room", "BaseRate": 60.5 }], окончательное значение поля "Комнаты" будет [{ "Type": "Standard Room" }, { "Type": "Budget Room", "BaseRate": 60.5 }]. Он не будет добавлять или объединять новые и существующие значения.
    объединитьИлиЗагрузить Ведет себя как слияние, если документ существует, и отправляется, если документ является новым. Это наиболее распространенное действие для добавочных обновлений.
    загрузить Аналогично "upsert", где документ вставляется, если этот документ новый, и обновляется или заменяется, если он существует. Если в документе отсутствуют значения, необходимые индексу, значение поля документа устанавливается в null.

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

Замечание

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

Ответы

Код состояния 200 возвращается для успешного ответа, что означает, что все элементы надёжно сохранены и начнут индексироваться. Индексирование выполняется в фоновом режиме и делает новые документы доступными (т. е. запрашиваемыми и доступными для поиска) через несколько секунд после завершения операции индексирования. Конкретная задержка зависит от нагрузки на службу.

Успешное индексирование определяется свойством состояния, которое установлено в значение true для всех элементов, а также свойство statusCode, которое установлено в значение 201 (для только что отправленных документов) или 200 (для объединенных или удаленных документов):

{
  "value": [
    {
      "key": "unique_key_of_new_document",
      "status": true,
      "errorMessage": null,
      "statusCode": 201
    },
    {
      "key": "unique_key_of_merged_document",
      "status": true,
      "errorMessage": null,
      "statusCode": 200
    },
    {
      "key": "unique_key_of_deleted_document",
      "status": true,
      "errorMessage": null,
      "statusCode": 200
    }
  ]
}

Код состояния 207 возвращается, когда по крайней мере один элемент не был успешно индексирован. Элементы, которые не были индексированы, имеют поле состояния, равное false. Свойства errorMessage и statusCode указывают причину ошибки индексирования:

{
  "value": [
    {
      "key": "unique_key_of_document_1",
      "status": false,
      "errorMessage": "The search service is too busy to process this document. Please try again later.",
      "statusCode": 503
    },
    {
      "key": "unique_key_of_document_2",
      "status": false,
      "errorMessage": "Document not found.",
      "statusCode": 404
    },
    {
      "key": "unique_key_of_document_3",
      "status": false,
      "errorMessage": "Index is temporarily unavailable because it was updated with the 'allowIndexDowntime' flag set to 'true'. Please try again later.",
      "statusCode": 422
    }
  ]
}  

Свойство errorMessage указывает причину ошибки индексирования, если это возможно.

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

Код состояния Значение Повторная попытка Примечания.
200 Документ был успешно изменен или удален. n/a Операции удаления являются идемпотентными. То есть, даже если ключ документа не существует в индексе, попытка удаления с этим ключом приводит к коду состояния 200.
201 Документ был успешно создан. n/a
400 В документе произошла ошибка, которая препятствовала индексации. нет Сообщение об ошибке в ответе указывает, что неправильно с документом.
404 Документ не удалось объединить, так как заданный ключ не существует в индексе. нет Эта ошибка не возникает при загрузке, так как она создает новые документы, и не возникает при удалении, поскольку процесс является идемпотентным.
409 Конфликт версии обнаружен при попытке индексировать документ. Да Это может произойти при нескольких одновременных попытках индексирования одного документа.
422 Индекс временно недоступен, так как он был обновлен с флагом AllowIndexDowntime с значением true. Да
429 Слишком много запросов Да Если этот код ошибки возникает во время индексирования, обычно это означает, что вы работаете с низким уровнем хранилища. По мере того как вы приближаетесь к ограничениям хранения, служба может ввести состояние, в котором нельзя добавлять или обновлять до тех пор, пока не удалите некоторые документы. Дополнительные сведения см. в разделе "Планирование емкости" и управление ими, если требуется больше хранилища или освободить место, удалив документы.
503 (Сервис временно недоступен) Служба поиска временно недоступна, возможно, из-за тяжелой нагрузки. Да Следует подождать, прежде чем предпринимать повторную попытку. В противном случае вы можете только увеличить время недоступности службы.

Если клиентский код часто встречает ответ 207, одна из возможных причин заключается в том, что система находится под нагрузкой. Это можно подтвердить, проверив свойство statusCode для 503. Если код состояния равен 503, рекомендуется ограничивать запросы индексирования. В противном случае, если индексирование трафика не утихает, система может начать отклонять все запросы с ошибками 503.

Код состояния 429 указывает, что превышена квота на количество документов на индекс. Необходимо либо обновить для более высоких ограничений емкости , либо создать новый индекс.

Замечание

При отправке DateTimeOffset значений с данными часового пояса в индекс поиск Azure AI нормализует эти значения в формате UTC. Например, 2024-01-13T14:03:00-08:00 хранится как 2024-01-13T22:03:00Z. Если необходимо сохранить сведения часового пояса, добавьте дополнительный столбец в индекс для этой точки данных.

Советы по добавочному индексированию

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

  • Если вы выполняете вызовы индекса непосредственно через push API, используйте mergeOrUpload как действие поиска.

  • Полезные данные должны содержать ключи или идентификаторы каждого документа, которые требуется добавить, обновить или удалить.

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

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

  • Чтобы объединить встроенные изменения в коллекцию строк, укажите полное значение. tags Помните пример поля из предыдущего раздела. Новые значения перезаписывают старые значения для всего поля и не объединяются в содержимое поля.

Ниже приведен пример REST API , демонстрирующий следующие советы:

### Get Stay-Kay City Hotel by ID
GET  {{baseUrl}}/indexes/hotels-vector-quickstart/docs('1')?api-version=2024-07-01  HTTP/1.1
    Content-Type: application/json
    api-key: {{apiKey}}

### Change the description, city, and tags for Stay-Kay City Hotel
POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search.index?api-version=2024-07-01  HTTP/1.1
  Content-Type: application/json
  api-key: {{apiKey}}

    {
        "value": [
            {
            "@search.action": "mergeOrUpload",
            "HotelId": "1",
            "Description": "I'm overwriting the description for Stay-Kay City Hotel.",
            "Tags": ["my old item", "my new item"],
            "Address": {
                "City": "Gotham City"
                }
            }
        ]
    }
       
### Retrieve the same document, confirm the overwrites and retention of all other values
GET  {{baseUrl}}/indexes/hotels-vector-quickstart/docs('1')?api-version=2024-07-01  HTTP/1.1
    Content-Type: application/json
    api-key: {{apiKey}}

Обновление схемы индекса

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

Обновления без перекомпиляции

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

Порядок операций:

  1. Получите определение индекса.

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

  3. Обновите схему индекса в службе поиска.

  4. Обновите содержимое индекса , чтобы соответствовать измененной схеме, если вы добавили новое поле. Для всех остальных изменений используется существующее индексированное содержимое as-is.

При обновлении схемы индекса для включения нового поля существующие документы в индексе получают значение NULL для этого поля. В следующем задании индексирования значения из внешних исходных данных заменяют значения NULL, добавленные поиском ИИ Azure.

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

Обновления, требующие перестроения

Для некоторых изменений требуется удаление и перестроение индекса, заменив текущий индекс новым.

Действие Описание
Удаление поля Чтобы физически удалить все следы поля, необходимо перестроить индекс. Если немедленное перестроение нецелесообразно, вы можете изменить код приложения для перенаправления доступа от устаревшего поля или использовать параметры запроса searchFields и select, чтобы выбрать, какие поля должны быть рассмотрены и возвращены. Физически определение поля и содержимое остаются в индексе до следующего перестроения, когда применяется схема, которая не указывает на поле.
Изменение определения поля Для изменения имени поля, типа данных или определенных атрибутов индекса (доступных для поиска, фильтруемых, сортируемых, фасетируемых) требуется полное перестроение.
Назначение анализатора полю Анализаторы определяются в индексе, назначены полям, а затем вызываются во время индексирования, чтобы сообщить, как создаются маркеры. В любой момент можно добавить новое определение анализатора в индекс, но при создании поля можно назначить только анализатор. Это верно для свойств анализатора и indexAnalyzer . Свойство searchAnalyzer является исключением (вы можете назначить это свойство существующему полю).
Обновление или удаление определения анализатора в индексе Вы не можете удалить или изменить существующую конфигурацию анализатора (анализатор, токенизатор, фильтр маркеров или фильтр символов) в индексе, если вы не перестроите весь индекс.
Добавление поля в предложитель Если поле уже существует и вы хотите добавить его в конструкцию предложения , перестройте индекс.
Обновление службы или уровня Если вам нужна дополнительная емкость, проверьте, можно ли обновить службу или перейти на более высокую ценовую категорию. В противном случае необходимо создать новую службу и перестроить индексы с нуля. Чтобы автоматизировать этот процесс, можно использовать пример кода, который выполняет резервное копирование индекса в ряд JSON-файлов. Затем можно повторно создать индекс в указанной службе поиска.

Порядок операций:

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

  2. Рекомендуется использовать решение резервного копирования и восстановления для сохранения копии содержимого индекса. В C# и Python существуют решения. Рекомендуется использовать версию Python, так как она обновлена.

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

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

  4. Опубликуйте обновленный индекс, в котором тело запроса включает измененные определения полей и конфигурации.

  5. Загрузите индекс с документами из внешнего источника. Документы индексируются с помощью определений полей и конфигураций новой схемы.

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

Чтобы свести к минимуму нарушение кода приложения, рекомендуется создать псевдоним индекса. Код приложения ссылается на псевдоним, но можно обновить имя индекса, на который указывает псевдоним.

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

Начиная с версии REST API 2025-05-01-preview, поддержка ddescription теперь доступна. Этот читаемый человеком текст бесценен, когда система должна получить доступ к нескольким индексам и принять решение на основе описания. Рассмотрим сервер протокола контекста модели (MCP), который должен выбрать правильный индекс во время выполнения. Решение может основываться на описании, а не только на имени индекса.

Описание индекса — это обновление схемы, и его можно добавить, не перестроив весь индекс.

  • Длина строки составляет 4000 символов.
  • Содержимое должно быть удобочитаемым в Юникоде. Ваш вариант использования должен определить, какой язык следует использовать.

Поддержка описания индекса предоставляется в предварительной версии REST API, на портале Azure или в предварительном пакете azure SDK, который предоставляет эту функцию.

Портал Azure поддерживает последний api предварительной версии.

  1. Войдите на портал Azure и найдите службу поиска.

  2. В разделе"Индексы управления >поиском" выберите индекс.

  3. Выберите "Изменить JSON".

  4. Вставка "description", за которой следует описание. Значение должно быть меньше 4000 символов и в Юникоде.

    Снимок экрана: определение JSON индекса на портале Azure.

  5. Сохраните индекс.

Балансировка рабочих нагрузок

Индексирование не выполняется в фоновом режиме, но служба поиска будет балансировать все задания индексирования по текущим запросам. Во время индексирования можно отслеживать запросы на портале Azure, чтобы обеспечить своевременное выполнение запросов.

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

Проверка обновлений

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

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

Если вы добавили или переименовали поле, используйте select, чтобы вернуть это поле:

"search": "*",
"select": "document-id, my-new-field, some-old-field",
"count": true

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

Удаление осиротевших документов

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

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

  1. Определите, какое поле является ключом документа. На портале Azure можно просмотреть поля каждого индекса. Ключи документа — это строковые поля, обозначенные значком ключа, чтобы их было легче заметить.

  2. Проверьте значения поля ключа документа: search=*&$select=HotelId Простая строка проста, но если индекс использует поле в кодировке Base-64 или если документы поиска были созданы из parsingMode параметра, возможно, вы работаете со значениями, с которыми вы не знакомы.

  3. Просмотрите документ , чтобы проверить значение идентификатора документа и просмотреть его содержимое перед удалением. Укажите ключ или идентификатор документа в запросе. В следующих примерах показана простая строка для примера индекса Hotels и строка в кодировке Base-64 для ключа metadata_storage_path индекса cog-search-demo.

    GET https://[service name].search.windows.net/indexes/hotel-sample-index/docs/1111?api-version=2024-07-01
    
    GET https://[service name].search.windows.net/indexes/cog-search-demo/docs/aHR0cHM6Ly9oZWlkaWJsb2JzdG9yYWdlMi5ibG9iLmNvcmUud2luZG93cy5uZXQvY29nLXNlYXJjaC1kZW1vL2d1dGhyaWUuanBn0?api-version=2024-07-01
    
  4. Удалите документ с помощью удаления @search.action из индекса поиска.

    POST https://[service name].search.windows.net/indexes/hotels-sample-index/docs/index?api-version=2024-07-01
    Content-Type: application/json   
    api-key: [admin key] 
    {  
      "value": [  
        {  
          "@search.action": "delete",  
          "id": "1111"  
        }  
      ]  
    }
    

См. также