Pesquisa de termo parcial e padrões com caracteres especiais (hifens, curinga, regex, padrões)

Uma pesquisa de termo parcial refere-se a consultas que consistem em fragmentos de termo em que, em vez de um termo inteiro, você pode ter apenas o início, o meio ou o fim do termo (às vezes chamados de consultas de prefixo, infixo ou sufixo). Uma pesquisa de termo parcial pode incluir uma combinação de fragmentos, geralmente com caracteres especiais, como hifens, traços ou barras que fazem parte da cadeia de caracteres de consulta. Casos de uso comuns incluem partes de um número de telefone, URL, códigos ou palavras compostas com hifenização.

Termos parciais e caracteres especiais podem ser problemáticos se o índice não tiver um token que represente o fragmento de texto que você deseja pesquisar. Durante a fase de análise lexical da indexação (supondo o analisador padrão), os caracteres especiais são descartados, as palavras compostas são divididas e o espaço em branco é excluído. Se você estiver procurando um fragmento de texto que foi modificado durante a análise lexical, a consulta falhará porque nenhuma correspondência foi encontrada. Por exemplo, um número de telefone como +1 (425) 703-6214 (indexado como "1", "425", "703", "6214") não aparecerá em uma consulta "3-62" porque esse conteúdo não existe realmente no índice.

A solução é invocar um analisador durante a indexação que preserva uma cadeia de caracteres completa, incluindo espaços e caracteres especiais, se necessário, para que você possa incluir os espaços e os caracteres na cadeia de caracteres de consulta. Ter uma cadeia de caracteres inteira e não indexada permite padrões correspondentes para consultas "começa com" ou "termina com", em que o padrão que você fornece pode ser avaliado em relação a um termo que não é transformado pela análise lexical.

Se você precisar dar suporte a cenários de pesquisa que exigem conteúdo analisado e não analisado, considere a criação de dois campos em seu índice, um para cada cenário. Um campo passa por análise lexical. O segundo campo armazena uma cadeia de caracteres intacta, usando um analisador de preservação de conteúdo que emite tokens de cadeia de caracteres inteiras para padrões correspondentes.

A Pesquisa de IA do Azure examina os termos com token completo no índice e não encontrará uma correspondência em um termo parcial, a menos que você inclua operadores de espaço reservado curinga (* e ?) ou formate a consulta como uma expressão regular.

Os termos parciais são especificados usando estas técnicas:

  • Consultas de expressões regulares podem ser qualquer expressão regular que seja válida no Apache Lucene.

  • Os operadores curinga com correspondência de prefixo referem-se a um padrão geralmente reconhecido que inclui o início de um termo, seguido pelos operadores de sufixo * ou ?, como a correspondência search=cap* em "Cap'n Jack's Waterfront Inn" ou "Gacc Capital". Há suporte para correspondência de prefixo tanto na sintaxe de consulta simples quanto na sintaxe de consulta completa do Lucene.

  • O curinga com correspondência de infixo e sufixo posiciona os operadores * e ? dentro de um termo ou no início dele e requer a sintaxe de expressão regular (onde a expressão é colocada entre barras). Por exemplo, a cadeia de caracteres de consulta (search=/.*numeric.*/) retorna resultados em "alfanumérico" e "alfanuméricos" como correspondências de sufixo e infixo.

Para expressão regular, curinga e pesquisa difusa, os analisadores não são usados no momento da consulta. Para essas formas de consulta, que o analisador detecta pela presença de operadores e delimitadores, a cadeia de caracteres de consulta é passada para o mecanismo sem análise lexical. Para essas formas de consulta, o analisador especificado no campo é ignorado.

Observação

Quando uma cadeia de caracteres de consulta parcial inclui caracteres, como barras em um fragmento de URL, pode ser necessário adicionar caracteres de escape. Em JSON, uma barra / é seguida pelo caractere de escape barra invertida \. Como tal, search=/.*microsoft.com\/azure\/.*/ é a sintaxe para o fragmento de URL "microsoft.com/azure/".

Resolvendo problemas de pesquisa parcial/padrão

Quando você precisar pesquisar em fragmentos ou padrões ou caracteres especiais, poderá substituir o analisador padrão por um analisador personalizado que opera sob regras de geração de tokens mais simples, retendo toda a cadeia de caracteres no índice.

A abordagem tradicional é parecida com esta:

  1. Definir um segundo campo para armazenar uma versão intacta da cadeia de caracteres (supondo que você deseja texto analisado e não analisado no momento da consulta)
  2. Avaliar e escolher entre os vários analisadores que emitem tokens no nível certo de granularidade
  3. Atribuir o analisador ao campo
  4. Compilar e testar o índice

1 - Criar um campo dedicado

Os analisadores determinam como os termos são indexados em um índice. Como os analisadores são atribuídos por campo, você pode criar campos no seu índice para otimizar cenários diferentes. Por exemplo, você pode definir "featureCode" e "featureCodeRegex" para dar suporte à pesquisa de texto completo regular no primeiro e à correspondência de padrão avançada no segundo. Os analisadores atribuídos a cada campo determinam como o conteúdo de cada campo é indexado no índice.

{
  "name": "featureCode",
  "type": "Edm.String",
  "retrievable": true,
  "searchable": true,
  "analyzer": null
},
{
  "name": "featureCodeRegex",
  "type": "Edm.String",
  "retrievable": true,
  "searchable": true,
  "analyzer": "my_custom_analyzer"
},

2 - Definir um analisador

Ao escolher um analisador que produz tokens de termo inteiro, os seguintes analisadores são opções comuns:

Analisador Comportamentos
analisadores de linguagem Preserva hifens em palavras compostas ou cadeias de caracteres, mutações de vogal e formas verbais. Se os padrões de consulta incluírem traços, usar um analisador de linguagem pode ser suficiente.
Palavra-chave O conteúdo de todo o campo é indexado como um único termo.
whitespace Separa somente em espaços em branco. Os termos que incluem traços ou outros caracteres são tratados como um único token.
analisador personalizado (recomendado) A criação de um analisador personalizado permite especificar o criador de token e o filtro de token. Os analisadores anteriores devem ser usados no estado em que se encontram. Um analisador personalizado permite que você escolha quais criadores de tokens e filtros de tokens usar.

Uma combinação recomendada é o criador de token de palavra-chave com um filtro de token em minúsculas. Por si só, o analisador de palavra-chave interno não transforma texto em letras maiúsculas em letras minúsculas, o que pode causar falhas nas consultas. Um analisador personalizado oferece a você um mecanismo para adicionar o filtro de token em minúsculas.

Usando um cliente REST, você pode adicionar a chamada REST do analisador de teste para inspecionar a saída tokenizada.

O índice precisa existir no serviço de pesquisa, mas pode estar vazio. Dado um índice existente e um campo contendo traços ou termos parciais, você pode experimentar vários analisadores sobre termos específicos para ver quais tokens são emitidos.

  1. Primeiro, verifique o analisador padrão para ver como os termos são indexados por padrão.

    {
    "text": "SVP10-NOR-00",
    "analyzer": "standard"
    }
    
  2. Avalie a resposta para ver como o texto está indexado no índice. Observe se cada termo está em letra minúscula, se os hifens foram removidos e se as substrings foram divididas em tokens individuais. Somente as consultas que correspondem a esses tokens retornarão este documento nos resultados. Uma consulta que inclui "10-NOR" falhará.

    {
        "tokens": [
            {
                "token": "svp10",
                "startOffset": 0,
                "endOffset": 5,
                "position": 0
            },
            {
                "token": "nor",
                "startOffset": 6,
                "endOffset": 9,
                "position": 1
            },
            {
                "token": "00",
                "startOffset": 10,
                "endOffset": 12,
                "position": 2
            }
        ]
    }
    
  3. Agora, modifique a solicitação para usar o analisador whitespace ou keyword:

    {
    "text": "SVP10-NOR-00",
    "analyzer": "keyword"
    }
    
  4. Agora, a resposta consiste em um único token, com maiúsculas, com traços preservados como parte da cadeia de caracteres. Se você precisar pesquisar em um padrão ou em um termo parcial, como "10-NOR", o mecanismo de consulta agora terá a base para encontrar uma correspondência.

    {
    
        "tokens": [
            {
                "token": "SVP10-NOR-00",
                "startOffset": 0,
                "endOffset": 12,
                "position": 0
            }
        ]
    }
    

Importante

Lembre-se de que os analisadores de consulta geralmente são os termos minúsculos em uma expressão de pesquisa ao criar a árvore de consulta. Se você estiver usando um analisador que não usa entradas de texto em letras minúsculas durante a indexação e não estiver obtendo os resultados esperados, isso pode ser o motivo. A solução é adicionar um filtro de token em letras minúsculas, conforme descrito na seção "Usar analisadores personalizados", abaixo.

3 - Configurar um analisador

Se você estiver avaliando analisadores ou avançando com uma configuração específica, será necessário especificar o analisador na definição de campo e, possivelmente, configurar o próprio analisador se você não estiver usando um analisador interno. Ao trocar analisadores, normalmente você precisa recompilar o índice (remover, recriar e recarregar).

Usar analisadores internos

Os analisadores internos podem ser especificados pelo nome em uma propriedade analyzer de uma definição de campo, sem nenhuma configuração adicional necessária no índice. O exemplo a seguir demonstra como você definiria o analisador whitespace em um campo.

Para outros cenários e para saber mais sobre outros analisadores internos, consulte Analisadores internos.

    {
      "name": "phoneNumber",
      "type": "Edm.String",
      "key": false,
      "retrievable": true,
      "searchable": true,
      "analyzer": "whitespace"
    }

Usar analisadores personalizados

Se você estiver usando um analisador personalizado, defina-o no índice com uma combinação definida pelo usuário de criador de tokens, filtro de token, com as definições de configuração possíveis. Em seguida, faça referência a ele em uma definição de campo, exatamente como você faria com um analisador interno.

Quando o objetivo é a geração de tokens de termo inteiro, é recomendado um analisador personalizado que consiste em um criador de token de palavra-chave e um filtro de token em letras minúsculas.

  • O criador de token de palavra-chave cria um único token para todo o conteúdo de um campo.
  • O filtro de token em letras minúsculas transforma letras maiúsculas em texto em minúsculas. Normalmente, os analisadores de consulta transformam todas as entradas de texto em maiúsculas em texto em minúsculas. Letras minúsculas uniformizam as entradas com os termos indexados.

O exemplo a seguir ilustra um analisador personalizado que fornece o criador de tokens de palavra-chave e um filtro de token em minúsculas.

{
"fields": [
  {
  "name": "accountNumber",
  "analyzer":"myCustomAnalyzer",
  "type": "Edm.String",
  "searchable": true,
  "filterable": true,
  "retrievable": true,
  "sortable": false,
  "facetable": false
  }
],

"analyzers": [
  {
  "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
  "name":"myCustomAnalyzer",
  "charFilters":[],
  "tokenizer":"keyword_v2",
  "tokenFilters":["lowercase"]
  }
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": []
}

Observação

O criador de tokens keyword_v2 e o filtro de token lowercase são conhecidos pelo sistema e usam suas configurações padrão, motivo pelo qual você pode referenciá-los por nome sem precisar defini-los primeiro.

4 - Compilar e testar

Depois de definir um índice com analisadores e definições de campo que dão suporte ao seu cenário, carregue os documentos que têm cadeias de caracteres representativas para que você possa testar as consultas de cadeias de caracteres parciais.

Use um cliente REST para consultar os termos parciais e caracteres especiais descritos neste artigo.

As seções anteriores explicaram a lógica. Esta seção percorre cada API que você deve chamar ao testar sua solução.

  • Excluir índice remove um índice existente com o mesmo nome para que você possa recriá-lo.

  • Criar índice cria a estrutura do índice no seu serviço de pesquisa, incluindo definições e campos do analisador com uma especificação do analisador.

  • Carregar documentos importa documentos que têm estrutura igual a do índice, além de conteúdo pesquisável. Após essa etapa, o seu índice estará pronto para consulta ou teste.

  • O analisador de teste foi introduzido em Definir um analisador. Teste algumas das cadeias de caracteres no índice usando vários analisadores para entender como os termos são indexados.

  • Documentos de pesquisa explica como construir uma solicitação de consulta, usando sintaxe simples ou a sintaxe Lucene completa para caracteres curinga e expressões regulares.

    Para consultas de termo parcial, como consultar "3-6214" para encontrar uma correspondência em "+ 1 (425) 703-6214", você pode usar a sintaxe simples: search=3-6214&queryType=simple.

    Para consultas de infixo e de sufixo, como consultar "num" ou "numérico" para encontrar uma correspondência em "alfanumérico", use a sintaxe Lucene completa e uma expressão regular: search=/.*num.*/&queryType=full

Desempenho de consulta de ajuste

Se você implementar a configuração recomendada que inclui o criador de token keyword_v2 e o filtro de token em letras minúsculas, poderá notar uma redução no desempenho da consulta devido ao processamento adicional de filtro de token sobre os tokens existentes no índice.

O exemplo a seguir adiciona um EdgeNGramTokenFilter para fazer correspondências de prefixo mais rapidamente. Os tokens são gerados em combinações de 2 a 25 caracteres que incluem caracteres. Veja um exemplo de progressão de dois para sete tokens: MS, MSF, MSFT, MSFT/, MSFT/S, MSFT/SQ, MSFT/SQL.

Como você pode imaginar, a geração de tokens adicionais resulta em um índice maior. Se você tiver capacidade suficiente para acomodar o índice maior, essa abordagem com seu tempo de resposta mais rápido poderá ser a melhor solução.

{
"fields": [
  {
  "name": "accountNumber",
  "analyzer":"myCustomAnalyzer",
  "type": "Edm.String",
  "searchable": true,
  "filterable": true,
  "retrievable": true,
  "sortable": false,
  "facetable": false
  }
],

"analyzers": [
  {
  "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
  "name":"myCustomAnalyzer",
  "charFilters":[],
  "tokenizer":"keyword_v2",
  "tokenFilters":["lowercase", "my_edgeNGram"]
  }
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": [
  {
  "@odata.type":"#Microsoft.Azure.Search.EdgeNGramTokenFilterV2",
  "name":"my_edgeNGram",
  "minGram": 2,
  "maxGram": 25,
  "side": "front"
  }
]
}

Próximas etapas

Este artigo explica como os analisadores contribuem para problemas de consulta e solucionam problemas de consulta. Como uma próxima etapa, examine atentamente o impacto do analisador sobre a indexação e o processamento de consultas.