Pesquisa parcial de termos e padrões com caracteres especiais (hífenes, curinga, regex, padrões)

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

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 (assumindo o analisador padrão padrão), caracteres especiais são descartados, palavras compostas são divididas e espaço em branco é excluído. Se você estiver procurando por um fragmento de texto que foi modificado durante a análise lexical, a consulta falhará porque nenhuma correspondência foi encontrada. Considere este exemplo: um número de telefone como +1 (425) 703-6214 (tokenizado como "1", "425", "703", "6214") não aparecerá em uma "3-62" consulta porque esse conteúdo realmente não existe no índice.

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

Se você precisar oferecer suporte a cenários de pesquisa que exigem conteúdo analisado e não analisado, considere a criação de dois campos no í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 inteira para correspondência de padrões.

O Azure AI Search verifica termos tokenizados inteiros 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 utilizando estas técnicas:

  • As consultas de expressão regular podem ser qualquer expressão regular válida no Apache Lucene.

  • Operadores curinga com correspondência de prefixo refere-se a um padrão geralmente reconhecido que inclui o início de um termo, seguido por * operadores de ? sufixos, como search=cap* correspondência em "Cap'n Jack's Waterfront Inn" ou "Gacc Capital". A correspondência de prefixo é suportada na sintaxe de consulta Lucene simples e completa.

  • Curinga com correspondência de infixo e sufixo coloca os * operadores e ? dentro ou no início de um termo e requer sintaxe de expressão regular (onde a expressão é encerrada com barras para frente). Por exemplo, a cadeia de caracteres de consulta (search=/.*numeric.*/) retorna resultados em "alfanumérico" e "alfanumérico" 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 esses formulários de consulta, que o analisador deteta pela presença de operadores e delimitadores, a cadeia de caracteres de consulta é passada para o mecanismo sem análise lexical. Para esses formulários de consulta, o analisador especificado no campo é ignorado.

Nota

Quando uma cadeia de caracteres de consulta parcial inclui caracteres, como barras em um fragmento de URL, talvez seja necessário adicionar caracteres de escape. Em JSON, uma barra / para a frente é escapada com uma barra \para trás. Como tal, search=/.*microsoft.com\/azure\/.*/ é a sintaxe para o fragmento de URL "microsoft.com/azure/".

Resolução de problemas de pesquisa parcial/padrão

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

A abordagem tem a seguinte aparência:

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

1 - Crie um campo dedicado

Os analisadores determinam como os termos são tokenizados em um índice. Como os analisadores são atribuídos por campo, você pode criar campos em seu índice para otimizar para diferentes cenários. Por exemplo, você pode definir "featureCode" e "featureCodeRegex" para oferecer suporte à pesquisa regular de texto completo no primeiro e à correspondência avançada de padrões no segundo. Os analisadores atribuídos a cada campo determinam como o conteúdo de cada campo é tokenizado 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 prazo inteiro, os seguintes analisadores são escolhas comuns:

Analisador Comportamentos
analisadores de linguagem Preserva hífenes em palavras compostas ou strings, mutações vocálicas e formas verbais. Se os padrões de consulta incluírem traços, o uso de um analisador de linguagem pode ser suficiente.
palavra-chave O conteúdo de todo o campo é tokenizado como um único termo.
espaço em branco Separa apenas 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 tokenizador e o filtro de token. Os analisadores anteriores devem ser usados como estão. Um analisador personalizado permite que você escolha quais tokenizadores e filtros de token usar.

Uma combinação recomendada é o tokenizador de palavras-chave com um filtro de token minúsculo. Por si só, o analisador de palavras-chave integrado não coloca em minúsculas nenhum texto em maiúsculas, o que pode fazer com que as consultas falhem. Um analisador personalizado fornece um mecanismo para adicionar o filtro de token minúsculo.

Usando um cliente REST, você pode adicionar a chamada REST do Test Analyzer para inspecionar a saída tokenizada.

O índice deve 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 tentar 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 tokenizados por padrão.

    {
    "text": "SVP10-NOR-00",
    "analyzer": "standard"
    }
    
  2. Avalie a resposta para ver como o texto é tokenizado dentro do índice. Observe como cada termo é minúsculo, hífenes removido e substrings divididas em tokens individuais. Somente as consultas que correspondem a esses tokens retornarão esse documento nos resultados. Uma consulta que inclua "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 whitespace analisador keyword :

    {
    "text": "SVP10-NOR-00",
    "analyzer": "keyword"
    }
    
  4. Desta vez, a resposta consiste em um único token, em maiúsculas, com traços preservados como parte da cadeia de caracteres. Se você precisar pesquisar em um padrão ou um termo parcial, como "10-NOR", o mecanismo de consulta agora tem 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 usam letras minúsculas em uma expressão de pesquisa ao criar a árvore de consulta. Se você estiver usando um analisador que não introduz texto em minúsculas durante a indexação e não estiver obtendo os resultados esperados, esse pode ser o motivo. A solução é adicionar um filtro de token minúsculo, conforme descrito na seção "Usar analisadores personalizados" abaixo.

3 - Configurar um analisador

Quer esteja a avaliar analisadores ou a avançar com uma configuração específica, terá de especificar o analisador na definição de campo e, possivelmente, configurar o próprio analisador se não estiver a utilizar um analisador incorporado. Ao trocar analisadores, você normalmente precisa reconstruir o índice (soltar, recriar e recarregar).

Use analisadores integrados

Os analisadores internos podem ser especificados pelo nome em uma analyzer propriedade de uma definição de campo, sem necessidade de configuração extra no índice. O exemplo a seguir demonstra como você definiria o whitespace analisador 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"
    }

Use analisadores personalizados

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

Quando o objetivo é a tokenização de todo o prazo, recomenda-se um analisador personalizado que consiste em um tokenizador de palavras-chave e um filtro de token minúsculo.

  • O tokenizador de palavra-chave cria um único token para todo o conteúdo de um campo.
  • O filtro de token minúsculo transforma letras maiúsculas em texto minúsculo. Os analisadores de consulta geralmente minúsculas quaisquer entradas de texto em maiúsculas. A caixa inferior homogeneiza as entradas com os termos tokenizados.

O exemplo a seguir ilustra um analisador personalizado que fornece o tokenizador de palavra-chave e um filtro de token minúsculo.

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

Nota

O keyword_v2 tokenizador e lowercase o filtro de token são conhecidos pelo sistema e usam suas configurações padrão, e é por isso que você pode referenciá-los pelo nome sem ter que defini-los primeiro.

4 - Construir e testar

Depois de definir um índice com analisadores e definições de campo que suportam seu cenário, carregue documentos que tenham cadeias de caracteres representativas para que você possa testar consultas de cadeia de caracteres parciais.

Use um cliente REST para consultar 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 de índice em seu serviço de pesquisa, incluindo definições de analisador e campos com uma especificação de analisador.

  • Carregar documentos importa documentos com a mesma estrutura do seu índice, bem como conteúdo pesquisável. Após esta etapa, seu índice estará pronto para consulta ou teste.

  • O Test Analyzer foi introduzido em set an analyzer. Teste algumas das cadeias de caracteres em seu índice usando vários analisadores para entender como os termos são tokenizados.

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

    Para consultas parciais de termos, 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 infix e sufixo, como consultar "num" ou "num" para encontrar uma correspondência em "alfanumérico", use a sintaxe Lucene completa e uma expressão regular: search=/.*num.*/&queryType=full

Otimizar o desempenho de consultas

Se você implementar a configuração recomendada que inclui o tokenizador de keyword_v2 e o filtro de token minúsculo, poderá notar uma diminuição no desempenho da consulta devido ao processamento do filtro de token extra sobre os tokens existentes em seu índice.

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

A tokenização extra 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 pode 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óximos passos

Este artigo explica como os analisadores contribuem para problemas de consulta e resolvem problemas de consulta. Como próxima etapa, examine mais de perto os analisadores que afetam a indexação e o processamento de consultas.