Exemplos de sintaxe de pesquisa Lucene "completa" (consultas avançadas na Pesquisa de IA do Azure)

Ao construir consultas para o Azure AI Search, você pode substituir o padrão analisador de consulta simples pelo mais expansivo analisador de consulta Lucene, para formular expressões de consulta especializadas e avançadas.

O analisador Lucene suporta formatos de consulta complexas, como consultas com escopo de campo, pesquisa difusa, caractere curinga prefixo, sufixo e radical, pesquisa de proximidade, reforço de termos e pesquisa de expressão regular. A energia adicional vem com mais requisitos de processamento, portanto, você deve esperar um tempo de execução um pouco mais longo. Neste artigo, execute exemplos em etapas, que demonstram as operações de consulta baseadas na sintaxe completa.

Observação

Muitas construções de consulta especializadas habilitadas por meio da sintaxe de consulta Lucene completa não são texto analisado, o que pode ser surpreendente caso espera-se a lematização. A análise lexical é realizada somente em termos completos (uma consulta de termo ou de frase). Tipos de consulta com termos incompletos (consulta de prefixo, consulta de curinga, consulta de regex, consulta difusa) são adicionados diretamente à árvore de consulta, ignorando o estágio de análise. A única transformação realizada em termos de consulta parcial é colocá-los em letras minúsculas.

Índice do exemplo de hotéis

As consultas a seguir são baseadas em hotels-sample-index, que você pode criar seguindo as instruções neste guia de início rápido.

Exemplos de consultas são articuladas usando a API REST e solicitações POST. Você pode colá-los e executá-los em um cliente REST. Ou então, use a exibição JSON do Gerenciador de Pesquisa no portal do Azure. Na exibição JSON, você pode colar nos exemplos de consulta mostrados aqui neste artigo.

Os cabeçalhos de solicitação devem ter os seguintes valores:

Key Valor
Content-Type aplicativo/json
api-key <your-search-service-api-key>, uma consulta ou chave de administração

Os parâmetros de URI devem incluir o ponto de extremidade do serviço de pesquisa com o nome do índice, as coleções de docs, o comando de pesquisa e a versão da API, semelhante ao exemplo a seguir:

https://{{service-name}}.search.windows.net/indexes/hotels-sample-index/docs/search?api-version=2023-11-01

O corpo da solicitação deve ser formado como um JSON válido:

{
    "search": "*",
    "queryType": "full",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "count": true
}
  • "pesquisa" definida como * é uma consulta não especificada, equivalente a NULL ou a uma pesquisa vazia. Não é especialmente útil, mas é a pesquisa mais simples que você pode fazer e mostra todos os campos recuperáveis no índice, com todos os valores.

  • Definir a "QueryType" como "Full" invoca o analisador de consulta completa Lucene e é necessário para essa sintaxe.

  • Definir "select" como uma lista delimitada por vírgulas de campos é usado para composição de resultado de pesquisa, incluindo apenas os campos que são úteis no contexto dos resultados da pesquisa.

  • "count" retorna o número de documentos correspondentes aos critérios de pesquisa. Em uma cadeia de caracteres de pesquisa vazia, a contagem será todos os documentos no índice (50 no caso de hotels-sample-index).

Escopo de pesquisa em campo individual, expressões de pesquisa inseridas em um campo específico. Este exemplo pesquisa nomes de hotéis com o termo "Hotel", mas não "Motel". Você pode especificar vários campos usando AND.

Ao usar essa sintaxe de consulta, você pode omitir o parâmetro searchFields, quando os campos que você deseja consultar estão na expressão de pesquisa propriamente dita. Se você incluir searchFields na pesquisa de campo, o fieldName:searchExpression sempre terá precedência sobre searchFields.

POST /indexes/hotel-samples-index/docs/search?api-version=2023-11-01
{
    "search": "HotelName:(hotel NOT motel) AND Category:'Resort and Spa'",
    "queryType": "full",
    "select": "HotelName, Category",
    "count": true
}

A resposta para essa consulta deve ser semelhante ao exemplo a seguir, filtrado em "Resort e Spa", retornando hotéis que incluem "hotel" no nome, excluindo os resultados que incluem "motel" no nome.

"@odata.count": 4,
"value": [
    {
        "@search.score": 4.481559,
        "HotelName": "Nova Hotel & Spa",
        "Category": "Resort and Spa"
    },
    {
        "@search.score": 2.4524608,
        "HotelName": "King's Palace Hotel",
        "Category": "Resort and Spa"
    },
    {
        "@search.score": 2.3970203,
        "HotelName": "Triple Landscape Hotel",
        "Category": "Resort and Spa"
    },
    {
        "@search.score": 2.2953436,
        "HotelName": "Peaceful Market Hotel & Spa",
        "Category": "Resort and Spa"
    }
]

A expressão de pesquisa pode ser um único termo, uma frase, ou uma expressão mais complexa entre parênteses, opcionalmente com operadores boolianos. Alguns exemplos incluem o seguinte:

  • HotelName:(hotel NOT motel)
  • Address/StateProvince:("WA" OR "CA")
  • Tags:("free wifi" NOT "free parking") AND "coffee in lobby"

Coloque uma frase entre aspas se quiser que ambas as cadeias de caracteres sejam avaliadas como uma única entidade, como neste caso, pesquisar dois locais distintos no campo de Endereço/Estado. Dependendo do cliente, talvez seja necessário escapar das (\) as aspas.

O campo especificado em fieldName:searchExpression deve ser um campo pesquisável. Consulte Criar índice (API REST) para ver detalhes sobre como as definições de campo são atribuídas.

Correspondências de pesquisa difusa em termos semelhantes, incluindo palavras incorretas. Para fazer uma pesquisa difusa, acrescente o símbolo til ~ ao final de uma única palavra com um parâmetro opcional, um valor entre 0 e 2, que especifica a distância de edição. Por exemplo, blue~ ou blue~1 retornariam mar, amar e maré.

POST /indexes/hotel-samples-index/docs/search?api-version=2023-11-01
{
    "search": "Tags:conserge~",
    "queryType": "full",
    "select": "HotelName, Category, Tags",
    "searchFields": "HotelName, Category, Tags",
    "count": true
}

A resposta para esta consulta é resolvida como "concierge" nos documentos correspondentes, cortada para diminuir:

"@odata.count": 12,
"value": [
    {
        "@search.score": 1.1832147,
        "HotelName": "Secret Point Motel",
        "Category": "Boutique",
        "Tags": [
            "pool",
            "air conditioning",
            "concierge"
        ]
    },
    {
        "@search.score": 1.1819803,
        "HotelName": "Twin Dome Motel",
        "Category": "Boutique",
        "Tags": [
            "pool",
            "free wifi",
            "concierge"
        ]
    },
    {
        "@search.score": 1.1773309,
        "HotelName": "Smile Hotel",
        "Category": "Suite",
        "Tags": [
            "view",
            "concierge",
            "laundry service"
        ]
    },

Não há suporte diretamente para frases, mas você pode especificar uma correspondência difusa em cada termo de uma frase de várias partes, como search=Tags:landy~ AND sevic~. Esta expressão de consulta localiza 15 correspondências no "lavanderia".

Observação

As consultas difusas não são analisadas. Tipos de consulta com termos incompletos (consulta de prefixo, consulta de curinga, consulta de regex, consulta difusa) são adicionados diretamente à árvore de consulta, ignorando o estágio de análise. A única transformação realizada em termos de consulta parcial é colocá-los em letras minúsculas.

A pesquisa por proximidade encontra termos próximos em um documento. Insira um símbolo til "~" no final de uma frase seguida pelo número de palavras que criam o limite de proximidade.

Essa consulta pesquisa os termos "hotel" e "airport" a cada cinco palavras em um documento. As aspas são escapadas (\") para preservar a frase:

POST /indexes/hotel-samples-index/docs/search?api-version=2023-11-01
{
    "search": "Description: \"hotel airport\"~5",
    "queryType": "full",
    "select": "HotelName, Description",
    "searchFields": "HotelName, Description",
    "count": true
}

A resposta para essa consulta deve ser semelhante ao exemplo a seguir:

"@odata.count": 2,
"value": [
    {
        "@search.score": 0.6331726,
        "HotelName": "Trails End Motel",
        "Description": "Only 8 miles from Downtown.  On-site bar/restaurant, Free hot breakfast buffet, Free wireless internet, All non-smoking hotel. Only 15 miles from airport."
    },
    {
        "@search.score": 0.43032226,
        "HotelName": "Catfish Creek Fishing Cabins",
        "Description": "Brand new mattresses and pillows.  Free airport shuttle. Great hotel for your business needs. Comp WIFI, atrium lounge & restaurant, 1 mile from light rail."
    }
]

Exemplo 4: aumento de termos

O aumento de termos refere-se ao aumento da classificação de um documento caso contenha o termo aumentado, em relação aos documentos que não contêm o termo. Para aumentar um termo, use o símbolo circunflexo, ^, com um fator de aumento (um número) no final do termo que você está pesquisando. O padrão do fator de aumento é 1 e, embora ele deva ser positivo, ele pode ser menor que 1 (por exemplo, 0,2). O aumento de termos difere dos perfis de pontuação, em que os perfis de pontuação aumentam determinados campos, em vez de termos específicos.

Nessa consulta "before", pesquise "acesso à praia" e observe que há sete documentos que corresponderão em um ou em ambos os termos.

POST /indexes/hotel-samples-index/docs/search?api-version=2023-11-01
{
    "search": "beach access",
    "queryType": "full",
    "select": "HotelName, Description, Tags",
    "searchFields": "HotelName, Description, Tags",
    "count": true
}

Na verdade, há apenas um documento que corresponde ao "acesso" e, como é a única combinação, seu posicionamento é alto (segunda posição), embora o documento não tenha o termo "praia".

"@odata.count": 7,
"value": [
    {
        "@search.score": 2.2723424,
        "HotelName": "Nova Hotel & Spa",
        "Description": "1 Mile from the airport.  Free WiFi, Outdoor Pool, Complimentary Airport Shuttle, 6 miles from the beach & 10 miles from downtown."
    },
    {
        "@search.score": 1.5507699,
        "HotelName": "Old Carrabelle Hotel",
        "Description": "Spacious rooms, glamorous suites and residences, rooftop pool, walking access to shopping, dining, entertainment and the city center."
    },
    {
        "@search.score": 1.5358944,
        "HotelName": "Whitefish Lodge & Suites",
        "Description": "Located on in the heart of the forest. Enjoy Warm Weather, Beach Club Services, Natural Hot Springs, Airport Shuttle."
    },
    {
        "@search.score": 1.3433652,
        "HotelName": "Ocean Air Motel",
        "Description": "Oceanfront hotel overlooking the beach features rooms with a private balcony and 2 indoor and outdoor pools. Various shops and art entertainment are on the boardwalk, just steps away."
    },

Na consulta "after" repita a pesquisa, dessa vez, aumentando os resultados com o termo "praia" em relação ao termo "acesso". Uma versão da consulta legível para humanos é search=Description:beach^2 access. De acordo com seu cliente, você pode ter que expressar ^2 como %5E2.

Depois de aumentar o termo "praia", a combinação sobre o Old Carrabelle Hotel passa para o sexto lugar.

Exemplo 5: Regex

Uma pesquisa de expressão regular encontra uma correspondência com base no conteúdo entre as barras "/", como documentado na classe RegExp.

POST /indexes/hotel-samples-index/docs/search?api-version=2023-11-01
{
    "search": "HotelName:/(Mo|Ho)tel/",
    "queryType": "full",
    "select": "HotelName",
    "count": true
}

A resposta para essa consulta deve ser semelhante ao exemplo a seguir:

    "@odata.count": 22,
    "value": [
        {
            "@search.score": 1.0,
            "HotelName": "Days Hotel"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Triple Landscape Hotel"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Smile Hotel"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Pelham Hotel"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Sublime Cliff Hotel"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Twin Dome Motel"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Nova Hotel & Spa"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Scarlet Harbor Hotel"
        },

Observação

Consultas Regex não são analisadas. A única transformação realizada em termos de consulta parcial é colocá-los em letras minúsculas.

Você pode usar a sintaxe geralmente reconhecida para pesquisas com vários caracteres curinga (*) ou um caractere curinga (?). Observe que o analisador de consulta Lucene oferece suporte ao uso desses símbolos com um único termo e não uma frase.

Nesta consulta, pesquise nomes de hotel que contenham o prefixo 'sc'. Você não pode usar um símbolo * ou ? como o primeiro caractere de uma pesquisa.

POST /indexes/hotel-samples-index/docs/search?api-version=2023-11-01
{
    "search": "HotelName:sc*",
    "queryType": "full",
    "select": "HotelName",
    "count": true
}

A resposta para essa consulta deve ser semelhante ao exemplo a seguir:

    "@odata.count": 2,
    "value": [
        {
            "@search.score": 1.0,
            "HotelName": "Scarlet Harbor Hotel"
        },
        {
            "@search.score": 1.0,
            "HotelName": "Scottish Inn"
        }
    ]

Observação

Consultas com curingas não são analisadas. A única transformação realizada em termos de consulta parcial é colocá-los em letras minúsculas.

Próximas etapas

Experimente especificar as consultas no código. O link a seguir explica como configurar consultas de pesquisa usando SDKs do Azure.

Referência de sintaxe adicional, arquitetura de consulta e exemplos podem ser encontrados nos links a seguir: