Exemplos de sintaxe de pesquisa Lucene "completa" (consultas avançadas no Azure AI Search)

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

O analisador Lucene suporta formatos de consulta complexos, como consultas com escopo de campo, pesquisa difusa, pesquisa curinga de infix e sufixo, pesquisa de proximidade, aumento de termos e pesquisa de expressão regular. A potência extra vem com mais requisitos de processamento, então você deve esperar um tempo de execução um pouco maior. Neste artigo, você pode percorrer exemplos que demonstram operações de consulta com base na sintaxe completa.

Nota

Muitas das construções de consulta especializadas habilitadas através da sintaxe de consulta Lucene completa não são analisadas por texto, o que pode ser surpreendente se você esperar derivação ou lemmatização. A análise lexical só é realizada em termos completos (uma consulta de termos ou uma consulta de frase). Os tipos de consulta com termos incompletos (consulta de prefixo, consulta curinga, consulta regex, consulta difusa) são adicionados diretamente à árvore de consulta, ignorando a etapa de análise. A única transformação executada em termos de consulta parcial é a caixa baixa.

Índice de amostra de hotéis

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

Consultas de exemplo são articuladas usando a API REST e solicitações POST. Você pode colá-los e executá-los em um cliente REST. Ou use o modo de exibição JSON do Gerenciador de Pesquisa no portal do Azure. No modo de 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
Tipo de Conteúdo application/json
Chave API <your-search-service-api-key>, chave de consulta ou de administrador

Os parâmetros de URI devem incluir o ponto de extremidade do serviço de pesquisa com o nome do índice, coleções de documentos, comando de pesquisa e 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 do pedido deve ser formado como JSON válido:

{
    "search": "*",
    "queryType": "full",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "count": true
}
  • "search" definido como * é uma consulta não especificada, equivalente a pesquisa nula ou 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.

  • "queryType" definido como "full" invoca o analisador de consulta Lucene completo e é necessário para esta sintaxe.

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

  • "count" devolve o número de documentos que correspondem aos critérios de pesquisa. Em uma cadeia de pesquisa vazia, a contagem é de todos os documentos no índice (50 no hotels-sample-index).

Escopo de pesquisa em campo, expressões de pesquisa individuais incorporadas a 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 E.

Ao usar essa sintaxe de consulta, você pode omitir o searchFields parâmetro quando os campos que deseja consultar estiverem na própria expressão de pesquisa. Se você incluir searchFields com a pesquisa em campo, o sempre terá precedência sobre searchFields.fieldName:searchExpression

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 esta consulta deve ser semelhante ao exemplo a seguir, filtrado em "Resort and Spa", retornando hotéis que incluem "hotel" no nome, excluindo 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 ou uma frase, ou uma expressão mais complexa entre parênteses, opcionalmente com operadores booleanos. Alguns exemplos incluem o seguinte:

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

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

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

A pesquisa difusa corresponde a termos semelhantes, incluindo palavras com erros ortográficos. Para fazer uma pesquisa difusa, acrescente o símbolo til no 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 devolveria azul, azul e cola.

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
}

Resposta para esta consulta resolve para "concierge" nos documentos correspondentes, cortados para brevidade:

"@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"
        ]
    },

As frases não são suportadas diretamente, mas você pode especificar uma correspondência difusa em cada termo de uma frase com várias partes, como search=Tags:landy~ AND sevic~. Esta expressão de consulta encontra 15 correspondências em "serviço de lavandaria".

Nota

Consultas difusas, não são analisadas. Os tipos de consulta com termos incompletos (consulta de prefixo, consulta curinga, consulta regex, consulta difusa) são adicionados diretamente à árvore de consulta, ignorando a etapa de análise. A única transformação executada em termos de consulta parcial é a caixa inferior.

A pesquisa de proximidade localiza termos que estão próximos uns dos outros num documento. Insira um símbolo til "~" no final de uma frase seguido pelo número de palavras que criam o limite de proximidade.

Esta consulta procura os termos "hotel" e "aeroporto" dentro de 5 palavras um do outro 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 esta 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: Reforço de termos

Aumento de termos refere-se à classificação mais alta de um documento se ele contiver o termo impulsionado, em relação aos documentos que não contêm o termo. Para impulsionar um termo, use o acento circunflexo, ^símbolo com um fator de impulso (um número) no final do termo que você está pesquisando. O padrão do fator de impulso é 1 e, embora deva ser positivo, pode ser menor que 1 (por exemplo, 0,2). O aumento de termos difere dos perfis de pontuação na medida em que os perfis de pontuação impulsionam determinados campos, em vez de termos específicos.

Nesta consulta "antes", pesquise por "acesso à praia" e repare que existem sete documentos que correspondem a um ou a 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 em "acesso", e por ser a única correspondência, sua colocação é alta (segunda posição) mesmo que o documento esteja faltando 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 "depois", repita a pesquisa, desta vez impulsionando os resultados com o termo "praia" sobre o termo "acesso". Uma versão legível por humanos da consulta é search=Description:beach^2 access. Dependendo do seu cliente, você pode precisar expressar ^2 como %5E2.

Depois de impulsionar o termo "praia", a partida no Old Carrabelle Hotel desce para o sexto lugar.

Exemplo 5: Regex

Uma pesquisa de expressão regular encontra uma correspondência com base no conteúdo entre barras "/", conforme 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 esta 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"
        },

Nota

As consultas Regex não são analisadas. A única transformação executada em termos de consulta parcial é a caixa inferior.

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

Nesta consulta, procure nomes de hotéis que contenham o prefixo 'sc'. Não é possível 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 esta 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"
        }
    ]

Nota

As consultas curinga não são analisadas. A única transformação executada em termos de consulta parcial é a caixa inferior.

Próximos passos

Tente especificar consultas no código. O link a seguir aborda como configurar consultas de pesquisa usando os SDKs do Azure.

Mais referência de sintaxe, arquitetura de consulta e exemplos podem ser encontrados nos seguintes links: