Atualizar ou reconstruir um índice no IA do Azure Search
Esse artigo explica como atualizar um índice existente no IA do Azure Search com alterações de esquema ou alterações de conteúdo através de indexação incremental. Explica as circunstâncias sob as quais as reconstruções são necessárias e fornece recomendações para mitigar os efeitos das reconstruções em pedidos de consulta em curso.
Durante o desenvolvimento ativo, é comum remover e reconstruir índices quando você está iterando sobre o design do índice. A maioria dos desenvolvedores trabalha com uma pequena amostra representativa de seus dados para que a reindexação seja mais rápida.
Para alterações de esquema em aplicativos já em produção, recomendamos criar e testar um novo índice que execute lado a lado um índice existente. Use um alias de índice para trocar o novo índice, evitando alterações no código do aplicativo.
Atualizar conteúdo
A indexação incremental e a sincronização de um índice em relação às alterações nos dados de origem são fundamentais para a maioria dos aplicativos de pesquisa. Esta seção explica o fluxo de trabalho para atualizar o conteúdo do campo em um índice de pesquisa por meio da API REST, mas os SDKs do Azure fornecem uma funcionalidade equivalente.
O corpo da solicitação contém um ou mais documentos a serem indexados. Os documentos são identificados por uma chave exclusiva que diferencia maiúsculas de minúsculas. Cada documento está associado uma ação: "carregar", "excluir", "mesclar" ou "mergeOrUpload". As solicitações de carregamento devem incluir os dados do documento como um conjunto de pares de chave/valor.
{
"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 (key/value pairs matching index schema)
...
},
...
]
}
Utilize as mesmas técnicas para carregar documentos: Documentos – Índice (REST) ou uma API equivalente nos SDKs do Azure. Para obter mais informações sobre técnicas de indexação, veja Carregar documentos.
Para uma atualização grande, o envio em lote (até mil documentos por lote ou cerca de 16 MB por lote, o que for o limite primeiro) é recomendado e aprimora significativamente o desempenho da indexação.
Defina o parâmetro
@search.action
na API para determinar o efeito nos documentos existentes.Ação Efeito excluir Remove todo o documento do índice. Se você quiser remover um campo individual, use merge em vez disso, definindo o campo em questão como nulo. Documentos e campos excluídos não liberam espaço imediatamente no índice. A cada poucos minutos, um processo em segundo plano executa a exclusão física. Quer você use o portal do Azure ou uma API para retornar estatísticas de índice, poderá esperar um pequeno atraso antes que a exclusão seja refletida no portal e por meio de APIs. merge Atualiza um documento que já existe e reprova um documento que não pode ser encontrado. Merge substitui os valores existentes. Por esse motivo, verifique se há campos de coleção que contêm vários valores, como campos do tipo Collection(Edm.String)
. Por exemplo, se um campotags
começar com um valor de["budget"]
e você executar uma mesclagem com["economy", "pool"]
, o valor final do campotags
será["economy", "pool"]
. Não será["budget", "economy", "pool"]
.
O mesmo comportamento se aplica a coleções complexas. Se o documento contiver um campo de coleção complexo chamado Salas com um valor de[{ "Type": "Budget Room", "BaseRate": 75.0 }]
, e você executar uma mesclagem com um valor de[{ "Type": "Standard Room" }, { "Type": "Budget Room", "BaseRate": 60.5 }]
, o valor final do campo Salas será[{ "Type": "Standard Room" }, { "Type": "Budget Room", "BaseRate": 60.5 }]
. Ele não acrescentará nem mesclará valores novos e existentes.mergeOrUpload Comporta-se como mesclar se o documento existir e fazer upload se o documento for novo. Essa é a ação mais comum para atualizações incrementais. upload Semelhante a um "upsert" onde o documento é inserido se for novo e atualizado ou substituído se existir. Se o documento tiver valores ausentes que o índice requer, o valor do campo do documento será definido como nulo.
As consultas continuam a ser executadas durante a indexação, mas se você estiver atualizando ou removendo campos existentes, poderá esperar resultados mistos e uma maior incidência de limitação.
Observação
Não há garantias de ordenação para as quais a ação no corpo da solicitação é executada primeiro. Não é recomendável ter várias ações "mesclar" associadas ao mesmo documento em apenas um corpo de solicitação. Se houver várias ações "mesclar" necessárias para o mesmo documento, execute a mesclagem do lado do cliente antes de atualizar o documento no índice de pesquisa.
Respostas
O código de status 200 é retornado para uma resposta bem-sucedida, o que significa que todos os itens foram armazenados de maneira durável e começarão a ser indexados. A indexação é executada em segundo plano e disponibiliza novos documentos (ou seja, consultáveis e pesquisáveis) alguns segundos após a conclusão da operação de indexação. O atraso específico depende da carga sobre o serviço.
A indexação bem-sucedida é indicada pela propriedade de status sendo definida como true para todos os itens, bem como a propriedade statusCode
sendo definida como 201 (para documentos carregados recentemente) ou 200 (para documentos mesclados ou excluídos):
{
"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
}
]
}
O código de status 207 será retornado quando pelo menos um item não tiver sido indexado com êxito. Os itens que não foram indexados têm o campo status definido como false. As propriedades errorMessage
e statusCode
indicam o motivo do erro de indexação:
{
"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
}
]
}
A propriedade errorMessage
indica o motivo do erro de indexação, se possível.
A tabela a seguir explica os vários códigos de status de cada documento que podem ser retornados na resposta. Alguns códigos de status indicam problemas com a solicitação em si, enquanto outros indicam condições de erro temporárias. Você deve testar o último novamente após um atraso.
Código de status | Significado | Com nova tentativa | Observações |
---|---|---|---|
200 | O documento foi modificado ou excluído com êxito. | N/D | As operações de exclusão são idempotentes. Ou seja, mesmo se não existir uma chave de documento no índice, a tentativa de uma operação de exclusão com essa chave resulta em um código de status 200. |
201 | O documento foi criado com êxito. | N/D | |
400 | Ocorreu um erro no documento que o impediu de ser indexado. | Não | A mensagem de erro na resposta indica o que há de errado com o documento. |
404 | Não foi possível mesclar o documento porque a chave especificada não existe no índice. | Não | Esse erro não ocorre em carregamentos, uma vez que eles criam novos documentos e não ocorre em exclusões porque elas são idempotentes. |
409 | Foi detectado um conflito de versão durante a tentativa de indexar um documento. | Sim | Isso pode acontecer quando você está tentando indexar o mesmo documento mais de uma vez simultaneamente. |
422 | O índice está temporariamente indisponível porque ele foi atualizado com o sinalizador 'allowIndexDowntime' definido como 'verdadeiro'. | Sim | |
503 | O serviço de pesquisa está temporariamente indisponível, possivelmente devido a uma carga pesada. | Sim | Neste caso, seu código deverá ser colocado em espera antes de uma nova tentativa, sob o risco de prolongar a indisponibilidade do serviço. |
Se o seu código de cliente com frequência encontrar uma resposta 207, um motivo possível é que o sistema esteja sob carga. Você pode confirmar isso verificando a propriedade statusCode para 503. Se o statusCode é 503, recomendamos a limitação de solicitações de indexação. Caso contrário, se a indexação de tráfego não diminuir, o sistema poderá começar a rejeitar todas as solicitações com erros 503.
O código de status 429 indica que você excedeu sua cota no número de documentos por índice. Você deve criar um novo índice ou atualizar para limites de capacidade mais altos.
Observação
Quando você carrega valores de DateTimeOffset
com informações de fuso horário no índice, a Pesquisa de IA do Azure normaliza esses valores para UTC. Por exemplo, 2024-01-13T14:03:00-08:00 é armazenado como 2024-01-13T22:03:00Z. Se você precisar armazenar informações de fuso horário, adicione uma coluna extra ao índice para esse ponto de dados.
Dicas para indexação incremental
Indexadores automatizam a indexação incremental. Se você puder usar um indexador e se a fonte de dados oferecer suporte ao controle de alterações, você poderá executar o indexador em uma programação recorrente para adicionar, atualizar ou substituir conteúdo pesquisável para que ele seja sincronizado com seus dados externos.
Se você estiver fazendo chamadas de índice diretamente pela API de push, use
mergeOrUpload
como ação de pesquisa.A carga deve incluir as chaves ou identificadores de cada documento que você deseja adicionar, atualizar ou excluir.
Se o índice incluir campos vetoriais e você definir a propriedade
stored
como falsa,lembre-se de incluir o vetor na atualização parcial do documento, mesmo que o valor não tenha mudado. Um efeito colateral de definirstored
como falso é que os vetores são descartados durante uma operação de reindexação. Fornecer o vetor no conteúdo dos documentos evita que isso aconteça.Para atualizar o conteúdo de campos simples e subcampos em tipos complexos, liste apenas os campos que deseja alterar. Por exemplo, se você precisar apenas atualizar um campo de descrição, a carga deverá consistir na chave do documento e na descrição modificada. A omissão de outros campos mantém seus valores existentes.
Para mesclar alterações embutidas em uma coleção de cadeia de caracteres, forneça o valor inteiro. Lembre-se do exemplo do campo
tags
da seção anterior. Os novos valores substituem os valores antigos de um campo inteiro, e não há mesclagem dentro do conteúdo de um campo.
Aqui está um exemplo de API REST demonstrando essas dicas:
### 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}}
Atualizar um esquema de índice
O esquema de índice define as estruturas de dados físicas criadas no serviço de pesquisa, portanto, não há muitas alterações de esquema que você possa fazer sem incorrer em uma reconstrução completa.
Atualizações sem recompilação
A lista a seguir enumera as alterações de esquema que podem ser introduzidas perfeitamente em um índice existente. Geralmente, a lista inclui novos campos e funcionalidades usadas durante a execução da consulta.
- Adicionar um novo campo
- Defina o atributo
retrievable
em um campo existente - Atualizar
searchAnalyzer
em um campo que já possui umindexAnalyzer
- Adicionar uma nova definição de analisador em um índice (que pode ser aplicado a novos campos)
- Adicionar, atualizar ou excluir perfis de pontuação
- Adicionar, atualizar ou excluir synonymMaps
- Adicionar, atualizar ou excluir configurações semânticas
- Adicionar, atualizar ou excluir configurações de CORS
A ordem das operações é:
Revise o esquema com atualizações da lista anterior.
Atualize o esquema de índice no serviço de pesquisa.
Atualize o conteúdo do índice para corresponder ao seu esquema revisado se você adicionou um novo campo. Para todas as outras alterações, o conteúdo indexado existente é usado no estado em que se encontra.
Quando você atualiza um esquema de índice para incluir um novo campo, os documentos existentes no índice recebem um valor nulo para esse campo. No próximo trabalho de indexação, os valores dos dados de origem externa substituem os nulos adicionados pela Pesquisa de IA do Azure.
Não deve haver interrupções nas consultas durante as atualizações, mas os resultados das consultas poderão variar à medida que as atualizações entrarem em vigor.
Atualizações que exigem uma recompilação
Algumas modificações exigem a remoção e a recompilação do índice, substituindo um índice atual por um novo.
Ação | Descrição |
---|---|
Excluir um campo | Para remover fisicamente todos os rastreamentos de um campo, você precisa recriar o índice. Quando uma reconstrução imediata não for prática, você poderá modificar o código do aplicativo para redirecionar o acesso de um campo obsoleto ou usar os parâmetros de consulta searchFields e select para escolher quais campos serão pesquisados e retornados. Fisicamente, a definição e o conteúdo do campo permanecem no índice até a próxima recompilação, quando você aplica um esquema que omite o campo em questão. |
Alterar uma definição de campo | As revisões de um nome de campo, tipo de dados ou atributos de índice específicos (pesquisáveis, filtráveis, classificáveis, facetable) exigem uma reconstrução completa. |
Atribuir um analisador a um campo | Os analisadores são definidos em um índice, atribuídos a campos e, em seguida, invocados durante a indexação para informar como os tokens são criados. É possível adicionar uma nova definição de analisador a um índice a qualquer momento, mas só é possível atribuir um analisador quando o campo é criado. Isso é verdadeiro para as propriedades analyzer e indexAnalyzer. A propriedade searchAnalyzer é uma exceção (é possível atribuir essa propriedade a um campo existente). |
Atualizar ou excluir uma definição de analisador em um índice | Não é possível excluir nem alterar uma configuração de analisador existente (analisador, gerador de token, filtro de token ou filtro de caracteres) no índice, a menos que você reconstrua todo o índice. |
Adicionar um campo a um sugestor | Se um campo já existir e você quiser adicioná-lo a uma construção Sugestores, reconstrua o índice. |
Alternar camadas | Não há suporte para atualizações in-loco. Se precisar de mais capacidade, crie um novo serviço e reconstrua seus índices do zero. Para ajudar a automatizar esse processo, você pode usar o código de exemplo index-backup-restore neste repositório de exemplo .NET do Azure AI Search. Esse aplicativo faz backup do seu índice em uma série de arquivos JSON e, em seguida, recria o índice em um serviço de pesquisa especificado. |
A ordem das operações é:
Obtenha uma definição de índice caso você precise dela para referência futura ou para usar como base para uma nova versão.
Considere usar uma solução de backup e restauração para preservar uma cópia do conteúdo do índice. Existem soluções em C# e em Python. Recomendamos a versão Python porque é mais atualizada.
Se você tiver capacidade em seu serviço de pesquisa, mantenha o índice existente enquanto cria e testa o novo.
Elimine o índice existente. As consultas direcionadas ao índice são descartadas imediatamente. Lembre-se de que a exclusão de um índice é irreversível, pois destrói o armazenamento físico para a coleção de campos e outros constructos.
Publique um índice revisado, onde o corpo da solicitação inclua definições e configurações de campo alteradas ou modificadas.
Carregue o índice com documentos de uma fonte externa. Os documentos são indexados usando as definições e configurações de campo do novo esquema.
Ao criar o índice, o armazenamento físico é alocado para cada campo no esquema de índice, com um índice invertido criado para cada campo pesquisável e um índice vetorial criado para cada campo vetorial. Os campos não pesquisáveis podem ser usados em filtros ou expressões, mas não têm índices invertidos e não são pesquisáveis em texto completo ou difuso. Em uma reconstrução de índice, esses índices invertidos e índices vetoriais são excluídos e recriados com base no esquema de índice fornecido.
Para minimizar a interrupção do código do aplicativo, considere criar um alias de índice. O código do aplicativo faz referência ao alias, mas você pode atualizar o nome do índice para o qual o alias aponta.
Balanceamento de cargas de trabalho
A indexação não é executada em segundo plano, mas o serviço de pesquisa balanceia os trabalhos de indexação em relação a consultas em andamento. Durante a indexação, você pode monitorar solicitações de consulta no portal do Azure para garantir que as consultas sejam completadas em tempo hábil.
Se as cargas de trabalho de indexação apresentarem níveis inaceitáveis de latência de consulta, realize uma análise de desempenho e examine estas dicas de desempenho para possível mitigação.
Verificar se há atualizações
Você pode começar a consultar um índice, assim que o primeiro documento for carregado. Se você souber a ID de um documento, a API REST de Procurar documento retorna o documento específico. Para testes mais amplos, você deve aguardar até que o índice seja totalmente carregado e, em seguida, usar consultas para verificar o contexto em que você espera ver.
Você pode usar o Search Explorer ou um cliente REST para verificar se há conteúdo atualizado.
Se você adicionou ou renomeou um campo, use select para retornar esse campo:
"search": "*",
"select": "document-id, my-new-field, some-old-field",
"count": true
O portal do Azure fornece o tamanho do índice e o tamanho do índice vetorial. Você pode verificar esses valores após atualizar um índice, mas lembre-se de esperar um pequeno atraso enquanto o serviço processa a alteração e de levar em conta as taxas de atualização do portal, que podem levar alguns minutos.
Excluir documentos órfãos
O Azure AI Search dá suporte a operações de nível de documento para que você possa pesquisar, atualizar e excluir um documento específico isoladamente. O exemplo a seguir mostra como excluir um documento.
A exclusão de um documento não libera espaço imediatamente no índice. A cada poucos minutos, um processo em segundo plano executa a exclusão física. Quer você use o portal ou uma API para retornar estatísticas de índice, você pode esperar um pequeno atraso antes que a exclusão seja refletida nas métricas da API e do portal do Azure.
Identifique qual campo é a chave do documento. No portal do Azure, você pode ver os campos de cada índice. Chaves de documento são campos de cadeia de caracteres e apresentam um ícone de chave para facilitar a identificação.
Verifique os valores do campo de chave do documento:
search=*&$select=HotelId
. Uma cadeia de caracteres simples é básica, mas se o índice usar um campo codificado em base 64 ou se os documentos de pesquisa forem gerados por uma configuraçãoparsingMode
, você poderá estar trabalhando com valores com os quais não está familiarizado.Procure o documento para verificar o valor da ID do documento e para examinar o conteúdo antes de excluí-lo. Especifique a chave ou a ID do documento na solicitação. Os exemplos a seguir ilustram uma cadeia de caracteres simples para o índice de exemplo Hotels e uma cadeia de caracteres codificada em base 64 para a chave metadata_storage_path do índice cog-search-demo index.
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
Exclua o documento usando delete
@search.action
para removê-lo do índice de pesquisa.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" } ] }