Analisadores para processamento de texto no Azure Cognitive Search

Um analisador é um componente do motor de busca de texto completo responsável pelo processamento de cadeias durante a indexação e a execução de consultas. O processamento de texto (também conhecido como análise lexical) é transformador, modificando uma cadeia através de ações como estas:

  • Remover palavras não essenciais (palavras-passe) e pontuação
  • Dividir expressões e palavras hifenizadas em partes de componentes
  • Minúsculas quaisquer palavras maiúsculas
  • Reduza as palavras em formulários de raiz primitivos para eficiência de armazenamento e para que as correspondências possam ser encontradas independentemente do tempo

A análise aplica-se a Edm.String campos marcados como "pesquisáveis", o que indica a pesquisa em texto completo.

Para os campos desta configuração, a análise ocorre durante a indexação quando os tokens são criados e, em seguida, novamente durante a execução de consultas quando as consultas são analisadas e o motor procura tokens correspondentes. É mais provável que ocorra uma correspondência quando o mesmo analisador é utilizado para indexação e consultas, mas pode definir o analisador para cada carga de trabalho de forma independente, dependendo dos seus requisitos.

Os tipos de consulta que não são pesquisa de texto completo, como filtros ou pesquisa difusa, não passam pela fase de análise no lado da consulta. Em vez disso, o analisador envia essas cadeias diretamente para o motor de busca, utilizando o padrão que fornece como base para a correspondência. Normalmente, estes formulários de consulta requerem tokens de cadeia inteira para que a correspondência de padrões funcione. Para garantir tokens de termos inteiros durante a indexação, poderá precisar de analisadores personalizados. Para obter mais informações sobre quando e por que motivo os termos de consulta são analisados, veja Pesquisa de texto completo no Azure Cognitive Search.

Para obter mais informações sobre a análise lexical, ouça o seguinte clip de vídeo para obter uma breve explicação.

Analisador predefinido

No Azure Cognitive Search, um analisador é invocado automaticamente em todos os campos de cadeia marcados como pesquisáveis.

Por predefinição, Azure Cognitive Search utiliza o analisador Standard do Apache Lucene (lucene padrão), que divide o texto em elementos que seguem as regras "Segmentação de Texto Unicode". O analisador padrão converte todos os carateres na forma minúscula. Tanto os documentos indexados como os termos de pesquisa passam pela análise durante a indexação e o processamento de consultas.

Pode substituir a predefinição numa base campo a campo. Os analisadores alternativos podem ser um analisador de idiomas para processamento linguístico, um analisador personalizado ou um analisador incorporado a partir da lista de analisadores disponíveis.

Tipos de analisadores

A lista seguinte descreve que analisadores estão disponíveis no Azure Cognitive Search.

Categoria Descrição
Analisador Lucene Padrão Predefinição. Não é necessária nenhuma especificação ou configuração. Este analisador para fins gerais tem um bom desempenho para muitos idiomas e cenários.
Analisadores incorporados Consumido como está e referenciado pelo nome. Existem dois tipos: idioma e idioma-agnóstico.

Os analisadores especializados (language-agnostic) são utilizados quando as entradas de texto requerem processamento especializado ou processamento mínimo. Exemplos de analisadores nesta categoria incluem Asciifolding, Keyword, Pattern, Simple, Stop, Whitespace.

Os analisadores de idiomas são utilizados quando precisa de suporte linguístico avançado para idiomas individuais. Azure Cognitive Search suporta 35 analisadores de linguagem Lucene e 50 analisadores de processamento de linguagem natural Microsoft.
Analisadores personalizados Refere-se a uma configuração definida pelo utilizador de uma combinação de elementos existentes, que consiste num tokenizador (obrigatório) e filtros opcionais (caráter ou token).

Alguns analisadores incorporados, como Padrão ou Parar, suportam um conjunto limitado de opções de configuração. Para definir estas opções, crie um analisador personalizado, composto pelo analisador incorporado e uma das opções alternativas documentadas em Analisadores incorporados. Tal como acontece com qualquer configuração personalizada, forneça um nome à sua nova configuração, como myPatternAnalyzer para a distinguir do analisador de Padrões Lucene.

Especificar analisadores

Definir um analisador é opcional. Regra geral, experimente utilizar primeiro o analisador lucene padrão predefinido para ver como funciona. Se as consultas não devolverem os resultados esperados, mudar para um analisador diferente é, muitas vezes, a solução certa.

  1. Se estiver a utilizar um analisador personalizado, adicione-o ao índice de pesquisa na secção "analisador". Para obter mais informações, veja Criar Índice e também Adicionar analisadores personalizados.

  2. Ao definir um campo, defina a propriedade "analisador" como um dos seguintes: um analisador incorporado , como a palavra-chave, um analisador de idiomas , como en.microsoft, ou um analisador personalizado (definido no mesmo esquema de índice).

      "fields": [
     {
       "name": "Description",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "analyzer": "en.microsoft",
       "indexAnalyzer": null,
       "searchAnalyzer": null
     },
    
  3. Se estiver a utilizar um analisador de idiomas, tem de utilizar a propriedade "analisador" para a especificar. As propriedades "searchAnalyzer" e "indexAnalyzer" não se aplicam aos analisadores de idiomas.

  4. Em alternativa, defina "indexAnalyzer" e "searchAnalyzer" para variar o analisador para cada carga de trabalho. Estas propriedades funcionam em conjunto como um substituto da propriedade "analisador", que tem de ser nula. Poderá utilizar diferentes analisadores para indexação e consultas se uma dessas atividades necessitar de uma transformação específica não necessária pela outra.

      "fields": [
     {
       "name": "ProductGroup",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "analyzer": null,
       "indexAnalyzer": "keyword",
       "searchAnalyzer": "standard"
     },
    

Quando adicionar analisadores

A melhor altura para adicionar e atribuir analisadores é durante o desenvolvimento ativo, quando a remoção e recriação de índices é rotina.

Uma vez que os analisadores são utilizados para tokenizar termos, deve atribuir um analisador quando o campo for criado. Na verdade, não é permitido atribuir um analisador ou indexAnalyzer a um campo que já tenha sido criado fisicamente (embora possa alterar a propriedade searchAnalyzer em qualquer altura sem impacto no índice).

Para alterar o analisador de um campo existente, terá de remover e recriar todo o índice (não pode reconstruir campos individuais). Para índices em produção, pode diferir uma reconstrução ao criar um novo campo com a nova atribuição de analisador e começar a utilizá-lo em vez do antigo. Utilize o Índice de Atualização para incorporar o novo campo e mergeOrUpload para o preencher. Mais tarde, como parte da manutenção planeada do índice, pode limpar o índice para remover campos obsoletos.

Para adicionar um novo campo a um índice existente, chame o Índice de Atualização para adicionar o campo e mergeOrUpload para o preencher.

Para adicionar um analisador personalizado a um índice existente, transmita o sinalizador "allowIndexDowntime" no Índice de Atualizações se quiser evitar este erro:

"Index update not allowed because it would cause downtime. In order to add new analyzers, tokenizers, token filters, or character filters to an existing index, set the 'allowIndexDowntime' query parameter to 'true' in the index update request. Note that this operation will put your index offline for at least a few seconds, causing your indexing and query requests to fail. Performance and write availability of the index can be impaired for several minutes after the index is updated, or longer for very large indexes."

Recomendações para trabalhar com analisadores

Esta secção oferece conselhos sobre como trabalhar com analisadores.

Um analisador para leitura-escrita, a menos que tenha requisitos específicos

Azure Cognitive Search permite-lhe especificar diferentes analisadores para indexação e pesquisa através das propriedades do campo "indexAnalyzer" e "searchAnalyzer". Se não for especificado, o conjunto de analisadores com a propriedade analisador é utilizado para indexação e pesquisa. Se o analisador não for especificado, é utilizado o analisador Lucene Padrão predefinido.

Uma regra geral consiste em utilizar o mesmo analisador para indexação e consulta, a menos que os requisitos específicos ditem o contrário. Certifique-se de que testa cuidadosamente. Quando o processamento de texto difere no tempo de pesquisa e indexação, corre o risco de incompatibilidade entre termos de consulta e termos indexados quando as configurações do analisador de pesquisa e indexação não estão alinhadas.

Testar durante o desenvolvimento ativo

Substituir o analisador padrão requer uma reconstrução do índice. Se possível, decida quais os analisadores a utilizar durante o desenvolvimento ativo, antes de lançar um índice para produção.

Inspecionar termos tokens

Se uma pesquisa não devolver os resultados esperados, o cenário mais provável é discrepâncias de tokens entre entradas de termos na consulta e termos tokens no índice. Se os tokens não forem os mesmos, as correspondências não se materializam. Para inspecionar a saída do tokenizer, recomendamos que utilize a API de Análise como uma ferramenta de investigação. A resposta consiste em tokens, tal como gerados por um analisador específico.

Exemplos REST

Os exemplos abaixo mostram as definições do analisador para alguns cenários principais.

Exemplo de analisador personalizado

Este exemplo ilustra uma definição de analisador com opções personalizadas. As opções personalizadas para filtros de carateres, tokens e filtros de tokens são especificadas separadamente como construções com nome e, em seguida, referenciadas na definição do analisador. Os elementos predefinidos são utilizados como estão e referenciados pelo nome.

A percorrer este exemplo:

  • Os analisadores são uma propriedade da classe de campo para um campo pesquisável.

  • Um analisador personalizado faz parte de uma definição de índice. Pode ser ligeiramente personalizado (por exemplo, personalizar uma única opção num filtro) ou personalizado em vários locais.

  • Neste caso, o analisador personalizado é "my_analyzer", que por sua vez utiliza um tokenizador padrão personalizado "my_standard_tokenizer" e dois filtros de token: filtro de asciação minúscula e personalizado "my_asciifolding".

  • Também define dois filtros de carateres personalizados "map_dash" e "remove_whitespace". O primeiro substitui todos os traços por carateres de sublinhado, enquanto o segundo remove todos os espaços. Os espaços têm de estar codificados em UTF-8 nas regras de mapeamento. Os filtros de caráter são aplicados antes da tokenização e afetarão os tokens resultantes (o tokenizador padrão quebra no traço e nos espaços, mas não no caráter de sublinhado).

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"my_analyzer"
        }
     ],
     "analyzers":[
        {
           "name":"my_analyzer",
           "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
           "charFilters":[
              "map_dash",
              "remove_whitespace"
           ],
           "tokenizer":"my_standard_tokenizer",
           "tokenFilters":[
              "my_asciifolding",
              "lowercase"
           ]
        }
     ],
     "charFilters":[
        {
           "name":"map_dash",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["-=>_"]
        },
        {
           "name":"remove_whitespace",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["\\u0020=>"]
        }
     ],
     "tokenizers":[
        {
           "name":"my_standard_tokenizer",
           "@odata.type":"#Microsoft.Azure.Search.StandardTokenizerV2",
           "maxTokenLength":20
        }
     ],
     "tokenFilters":[
        {
           "name":"my_asciifolding",
           "@odata.type":"#Microsoft.Azure.Search.AsciiFoldingTokenFilter",
           "preserveOriginal":true
        }
     ]
  }

Exemplo de atribuição de analisador por campo

O analisador Standard é a predefinição. Suponha que pretende substituir a predefinição por um analisador predefinido diferente, como o analisador de padrões. Se não estiver a definir opções personalizadas, só tem de especificá-la por nome na definição de campo.

O elemento "analisador" substitui o Analisador Standard numa base campo a campo. Não existe nenhuma substituição global. Neste exemplo, text1 utiliza o analisador de padrões e text2, que não especifica um analisador, utiliza a predefinição.

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text1",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"pattern"
        },
        {
           "name":"text2",
           "type":"Edm.String",
           "searchable":true
        }
     ]
  }

Misturar analisadores para operações de indexação e pesquisa

As APIs incluem atributos de índice para especificar diferentes analisadores para indexação e pesquisa. Os atributos searchAnalyzer e indexAnalyzer têm de ser especificados como um par, substituindo o atributo de analisador único.

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "indexAnalyzer":"whitespace",
           "searchAnalyzer":"simple"
        },
     ],
  }

Exemplo do analisador de idiomas

Os campos que contêm cadeias em idiomas diferentes podem utilizar um analisador de linguagem, enquanto outros campos mantêm a predefinição (ou utilizam outro analisador predefinido ou personalizado). Se utilizar um analisador de linguagem, este tem de ser utilizado para operações de indexação e pesquisa. Os campos que utilizam um analisador de linguagem não podem ter analisadores diferentes para indexação e pesquisa.

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "indexAnalyzer":"whitespace",
           "searchAnalyzer":"simple"
        },
        {
           "name":"text_fr",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"fr.lucene"
        }
     ],
  }

Exemplos de C#

Se estiver a utilizar os exemplos de código do SDK .NET, pode acrescentar estes exemplos para utilizar ou configurar analisadores.

Atribuir um analisador de idiomas

Qualquer analisador utilizado tal como está, sem configuração, é especificado numa definição de campo. Não existe nenhum requisito para criar uma entrada na secção [analisadores] do índice.

Os analisadores de idiomas são utilizados tal como estão. Para utilizá-las, chame LexicalAnalyzer, especificando o tipo LexicalAnalyzerName que fornece um analisador de texto suportado no Azure Cognitive Search.

Os analisadores personalizados são especificados da mesma forma na definição de campo, mas para que funcione, tem de especificar o analisador na definição do índice, conforme descrito na secção seguinte.

    public partial class Hotel
    {
       . . . 
        [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnLucene)]
        public string Description { get; set; }

        [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.FrLucene)]
        [JsonPropertyName("Description_fr")]
        public string DescriptionFr { get; set; }

        [SearchableField(AnalyzerName = "url-analyze")]
        public string Url { get; set; }
      . . .
    }

Definir um analisador personalizado

Quando for necessária personalização ou configuração, adicione uma construção de analisador a um índice. Assim que a definir, pode adicioná-la à definição de campo, conforme demonstrado no exemplo anterior.

Crie um objeto CustomAnalyzer . Um analisador personalizado é uma combinação definida pelo utilizador de um tokenizador conhecido, filtro de token zero ou mais e zero ou mais nomes de filtro de carateres:

O exemplo seguinte cria um analisador personalizado com o nome "url-analyze" que utiliza o token de uax_url_email e o filtro de token Em Minúsculas.

private static void CreateIndex(string indexName, SearchIndexClient adminClient)
{
   FieldBuilder fieldBuilder = new FieldBuilder();
   var searchFields = fieldBuilder.Build(typeof(Hotel));

   var analyzer = new CustomAnalyzer("url-analyze", "uax_url_email")
   {
         TokenFilters = { TokenFilterName.Lowercase }
   };

   var definition = new SearchIndex(indexName, searchFields);

   definition.Analyzers.Add(analyzer);

   adminClient.CreateOrUpdateIndex(definition);
}

Para obter mais exemplos, veja CustomAnalyzerTests.cs.

Passos seguintes

Pode encontrar uma descrição detalhada da execução de consultas na pesquisa em Texto completo no Azure Cognitive Search. O artigo utiliza exemplos para explicar comportamentos que podem parecer contra-intuitivos na superfície.

Para saber mais sobre analisadores, veja os seguintes artigos: