Exemplos de consultas de pesquisa "simples" na Pesquisa de IA do Azure

No Azure AI Search, a sintaxe de consulta simples invoca o analisador de consulta padrão para fazer uma pesquisa de texto completo. O analisador é rápido e manipula cenários comuns, incluindo pesquisa de texto completo, pesquisa filtrada e facetada e pesquisa de prefixo. Este artigo usa exemplos para ilustrar o uso de sintaxe simples em uma solicitação de documentos de pesquisa (API REST).

Observação

Uma sintaxe de consulta alternativa é Lucene Completa, com suporte para estruturas de consulta mais complexas como pesquisa com curinga e difusa. Para obter mais informações e exemplos, consulte usar a sintaxe Lucene completa.

Í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": "simple",
    "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 é particularmente útil, mas é a pesquisa mais simples que você pode fazer e ela mostra todos os campos recuperáveis no índice, com todos os valores.

  • "QueryType" definido como "simples" é o padrão e pode ser omitido, mas está incluído para reforçar ainda mais que os exemplos de consulta neste artigo são expressos na sintaxe simples.

  • 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).

A pesquisa de texto completo pode ser qualquer número de termos autônomos ou frases delimitadas por aspas, com ou sem operadores boolianos.

POST /indexes/hotel-samples-index/docs/search?api-version=2023-11-01
{
    "search": "pool spa +airport",
    "searchMode": "any",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Description",
    "count": true
}

Uma pesquisa de palavra-chave composta por termos ou frases importantes tendem a funcionar melhor. Os campos de cadeia de caracteres passam por análise de texto durante a indexação e a consulta, descartando palavras não essenciais como "o", "e", "isso". Para ver como uma cadeia de caracteres de consulta é indexada no índice, passe a cadeia de caracteres em uma chamada de análise de texto para o índice.

O parâmetro "searchMode" controla a precisão e a recuperação. Se você quiser mais recuperação, use o valor padrão "qualquer", que retorna um resultado se qualquer parte da cadeia de caracteres de consulta for correspondida. Se você favorecer a precisão, em que todas as partes da cadeia de caracteres devem ser correspondidas, altere searchMode para "Todos". Experimente a consulta acima de duas maneiras para ver como o searchMode altera o resultado.

A resposta para a consulta "pool de spa + aeroporto" deve ser semelhante ao exemplo a seguir, cortada para ser breve.

"@odata.count": 6,
"value": [
    {
        "@search.score": 7.3617697,
        "HotelId": "21",
        "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.",
        "Category": "Resort and Spa",
        "Tags": [
            "pool",
            "continental breakfast",
            "free parking"
        ]
    },
    {
        "@search.score": 2.5560288,
        "HotelId": "25",
        "HotelName": "Scottish Inn",
        "Description": "Newly Redesigned Rooms & airport shuttle.  Minutes from the airport, enjoy lakeside amenities, a resort-style pool & stylish new guestrooms with Internet TVs.",
        "Category": "Luxury",
        "Tags": [
            "24-hour front desk service",
            "continental breakfast",
            "free wifi"
        ]
    },
    {
        "@search.score": 2.2988036,
        "HotelId": "35",
        "HotelName": "Suites At Bellevue Square",
        "Description": "Luxury at the mall.  Located across the street from the Light Rail to downtown.  Free shuttle to the mall and airport.",
        "Category": "Resort and Spa",
        "Tags": [
            "continental breakfast",
            "air conditioning",
            "24-hour front desk service"
        ]
    }
]

Note a pontuação de pesquisa na resposta. Essa é a pontuação de relevância da correspondência. Por padrão, um serviço de pesquisa retornará as 50 principais correspondências com base nessa pontuação.

Pontuações uniformes de “1.0” ocorrem quando não há classificação, seja porque a pesquisa não era pesquisa de texto completo, seja porque nenhum critério foi fornecido. Por exemplo, em uma pesquisa vazia (Pesquisa = * ), as linhas retornam em ordem arbitrária. Quando você incluir critérios reais, verá as pontuações da pesquisa evoluírem para valores significativos.

Exemplo 2: pesquisar por ID

Quando você retorna resultados da pesquisa em uma consulta, uma próxima etapa lógica é fornecer uma página de detalhes que inclua mais campos do documento. Este exemplo mostra como retornar um único documento usando o Documento de pesquisa passando a ID do documento.

GET /indexes/hotels-sample-index/docs/41?api-version=2023-11-01

Todos os documentos possuem um identificador exclusivo. Se você estiver usando o portal, selecione o índice na guia Índices e examine as definições de campo para determinar qual campo é a chave. Usando REST, a chamada Obter Índice retorna a definição do índice no corpo da resposta.

A resposta para a consulta acima consiste no documento cuja chave é 41. Qualquer campo marcado como "recuperável" na definição do índice pode ser retornado nos resultados da pesquisa e renderizado em seu aplicativo.

{
    "HotelId": "41",
    "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.",
    "Description_fr": "L'hôtel front de mer surplombant la plage dispose de chambres avec balcon privé et 2 piscines intérieures et extérieures. Divers commerces et animations artistiques sont sur la promenade, à quelques pas.",
    "Category": "Budget",
    "Tags": [
        "pool",
        "air conditioning",
        "bar"
    ],
    "ParkingIncluded": true,
    "LastRenovationDate": "1951-05-10T00:00:00Z",
    "Rating": 3.5,
    "Location": {
        "type": "Point",
        "coordinates": [
            -157.846817,
            21.295841
        ],
        "crs": {
            "type": "name",
            "properties": {
                "name": "EPSG:4326"
            }
        }
    },
    "Address": {
        "StreetAddress": "1450 Ala Moana Blvd 2238 Ala Moana Ctr",
        "City": "Honolulu",
        "StateProvince": "HI",
        "PostalCode": "96814",
        "Country": "USA"
    }
}

Exemplo 3: filtrar em texto

A sintaxe de filtro é uma expressão OData que pode ser usada por ela mesma ou com search. Usado em conjunto, o filter é aplicado primeiro ao índice inteiro e, em seguida, a pesquisa é executada nos resultados do filtro. Os filtros, portanto, podem ser uma técnica útil para melhorar o desempenho da consulta, uma vez que reduzem o conjunto de documentos que a consulta de pesquisa precisa processar.

Os filtros podem ser definidos em qualquer campo marcado como filterable na definição do índice. No caso de hotels-sample-index, os campos filtráveis incluem categoria, marcas, ParkingIncluded, classificação e a maioria dos campos de endereço.

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
{
    "search": "art tours",
    "queryType": "simple",
    "filter": "Category eq 'Resort and Spa'",
    "searchFields": "HotelName,Description,Category",
    "select": "HotelId,HotelName,Description,Category",
    "count": true
}

A resposta para a consulta acima tem como escopo apenas os hotéis categorizados como "Relatório e Spa", que incluem os termos "arte" ou "tours". Nesse caso, há apenas uma correspondência.

{
    "@search.score": 2.8576312,
    "HotelId": "31",
    "HotelName": "Santa Fe Stay",
    "Description": "Nestled on six beautifully landscaped acres, located 2 blocks from the Plaza. Unwind at the spa and indulge in art tours on site.",
    "Category": "Resort and Spa"
}

Exemplo 4: funções de filtro

As expressões de filtro podem incluir as funções "search.ismatch" e "search.ismatchscoring", permitindo que você crie uma consulta de pesquisa dentro do filtro. Essa expressão de filtro usa um caractere curinga em livre para selecionar comodidades incluindo WiFi gratuito, estacionamento gratuito e assim por diante.

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
  {
    "search": "",
    "filter": "search.ismatch('free*', 'Tags', 'full', 'any')",
    "select": "HotelId, HotelName, Category, Description",
    "count": true
  }

A resposta para a consulta acima corresponde a 19 hotéis que oferecem comodidades livres. Observe que a pontuação de pesquisa é um "1.0" uniforme em todos os resultados. Isso ocorre porque a expressão de pesquisa é nula ou vazia, resultando em correspondências de filtro textual, mas sem pesquisa de texto completo. As pontuações de relevância são retornadas somente na pesquisa de texto completo. Se você estiver usando filtros sem search, verifique se você tem campos classificáveis suficientes para poder controlar a classificação de pesquisa.

"@odata.count": 19,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "31",
        "HotelName": "Santa Fe Stay",
        "Tags": [
            "view",
            "restaurant",
            "free parking"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "27",
        "HotelName": "Super Deluxe Inn & Suites",
        "Tags": [
            "bar",
            "free wifi"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "39",
        "HotelName": "Whitefish Lodge & Suites",
        "Tags": [
            "continental breakfast",
            "free parking",
            "free wifi"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "11",
        "HotelName": "Regal Orb Resort & Spa",
        "Tags": [
            "free wifi",
            "restaurant",
            "24-hour front desk service"
        ]
    },

Exemplo 5: filtros de intervalo

A filtragem de intervalos tem suporte por meio de filtros de expressões para qualquer tipo de dados. Os exemplos a seguir ilustram intervalos numéricos e de cadeia de caracteres. Os tipos de dados são importantes em filtros de intervalo e funcionam melhor quando os dados numéricos estão em campos numéricos e dados de cadeia de caracteres em campos de cadeia de caracteres. Dados numéricos em campos de cadeia de caracteres não são ideais como intervalos porque as cadeias de caracteres numéricas não são comparáveis.

A consulta a seguir é um intervalo numérico. Em hotels-sample-index, o único campo numérico filtrável é classificação.

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
{
    "search": "*",
    "filter": "Rating ge 2 and Rating lt 4",
    "select": "HotelId, HotelName, Rating",
    "orderby": "Rating desc",
    "count": true
}

A resposta para esta consulta deve ser semelhante ao exemplo a seguir, cortada para brevidade.

"@odata.count": 27,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "22",
        "HotelName": "Stone Lion Inn",
        "Rating": 3.9
    },
    {
        "@search.score": 1.0,
        "HotelId": "25",
        "HotelName": "Scottish Inn",
        "Rating": 3.8
    },
    {
        "@search.score": 1.0,
        "HotelId": "2",
        "HotelName": "Twin Dome Motel",
        "Rating": 3.6
    }
...

A próxima consulta é um filtro de intervalo sobre um campo de cadeia de caracteres (Address/StateProvince):

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
{
    "search": "*",
    "filter": "Address/StateProvince ge 'A*' and Address/StateProvince lt 'D*'",
    "select": "HotelId, HotelName, Address/StateProvince",
    "count": true
}

A resposta para esta consulta deve ser semelhante ao exemplo abaixo, cortada para brevidade. Neste exemplo, não é possível classificar por StateProvince porque o campo não tem atribuição de "classificável" na definição do índice.

"@odata.count": 9,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "9",
        "HotelName": "Smile Hotel",
        "Address": {
            "StateProvince": "CA "
        }
    },
    {
        "@search.score": 1.0,
        "HotelId": "39",
        "HotelName": "Whitefish Lodge & Suites",
        "Address": {
            "StateProvince": "CO"
        }
    },
    {
        "@search.score": 1.0,
        "HotelId": "7",
        "HotelName": "Countryside Resort",
        "Address": {
            "StateProvince": "CA "
        }
    },
...

O hotels-sample index inclui um campo Localização com coordenadas de latitude e longitude. Este exemplo usa a função geo.distance que filtra os documentos dentro da circunferência de um ponto inicial, até uma distância arbitrária (em quilômetros) que você fornece. É possível ajustar o último valor na consulta (10) para reduzir ou ampliar a área da superfície da consulta.

POST /indexes/v/docs/search?api-version=2023-11-01
{
    "search": "*",
    "filter": "geo.distance(Location, geography'POINT(-122.335114 47.612839)') le 10",
    "select": "HotelId, HotelName, Address/City, Address/StateProvince",
    "count": true
}

A resposta para essa consulta retorna todos os hotéis dentro de uma distância de 10 Kilometer das coordenadas fornecidas:

{
    "@odata.count": 3,
    "value": [
        {
            "@search.score": 1.0,
            "HotelId": "45",
            "HotelName": "Arcadia Resort & Restaurant",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        },
        {
            "@search.score": 1.0,
            "HotelId": "24",
            "HotelName": "Gacc Capital",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        },
        {
            "@search.score": 1.0,
            "HotelId": "16",
            "HotelName": "Double Sanctuary Resort",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        }
    ]
}

Exemplo 7: boolianos com searchMode

A sintaxe simples dá suporte a operadores boolianos na forma de caracteres ( +, -, | ) para dar suporte a and, or, e não à lógica de consulta. A pesquisa booliana se comporta como você pode esperar, com algumas exceções notáveis.

Nos exemplos anteriores, o parâmetro searchMode foi introduzido como um mecanismo para influenciar a precisão e a recall, com "searchMode": "any" favorecendo a recall (um documento que satisfaça qualquer um dos critérios é considerado uma correspondência) e "searchMode = All" favorecendo precisão (todos os critérios devem ser correspondidos em um documento).

No contexto de uma pesquisa booliana, o padrão "searchMode": "any" poderá ser confuso se você estiver empilhando uma consulta com vários operadores e obtendo resultados mais amplos em vez de mais restritos. Isso é particularmente verdade com NÃO, onde os resultados incluem todos os documentos "não contendo" um termo ou frase específico.

O exemplo a seguir ilustra esse cenário. A execução da consulta a seguir com searchmode (any) retorna 42 documentos: aqueles que contêm o termo "restaurante", além de todos os documentos que não têm a frase "ar-condicionado".

Observe que não há nenhum espaço entre o operador booliano ( - ) e a frase "ar-condicionado".

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
{
    "search": "restaurant -\"air conditioning\"",
    "searchMode": "any",
    "searchFields": "Tags",
    "select": "HotelId, HotelName, Tags",
    "count": true
}

Alterar para "searchMode": "all" impõe um efeito cumulativo em critérios e retorna um conjunto de resultados menor (7 Correspondências) que consiste em documentos que contêm o termo "restaurante", menos aqueles que contêm a frase "ar condicionado".

A resposta para esta consulta deveria agora ser semelhante ao exemplo a seguir, cortada para brevidade.

"@odata.count": 7,
"value": [
    {
        "@search.score": 2.5460577,
        "HotelId": "11",
        "HotelName": "Regal Orb Resort & Spa",
        "Tags": [
            "free wifi",
            "restaurant",
            "24-hour front desk service"
        ]
    },
    {
        "@search.score": 2.166792,
        "HotelId": "10",
        "HotelName": "Countryside Hotel",
        "Tags": [
            "24-hour front desk service",
            "coffee in lobby",
            "restaurant"
        ]
    },
...

Exemplo 8: Exibir os resultados

Nos exemplos anteriores, você aprendeu sobre parâmetros que afetam a composição dos resultados da pesquisa, incluindo select, que determina quais campos estão em um resultado, ordens de classificação e como incluir uma contagem de todas as correspondências. Este exemplo é uma continuação da composição de resultado da pesquisa na forma de parâmetros de paginação que permitem a você colocar em lote o número de resultados que aparecem em qualquer página específica.

Por padrão, um serviço de pesquisa retorna as principais correspondências 50. Para controlar o número de correspondências em cada página, use top para definir o tamanho do lote e, em seguida, use skip para pegar lotes subsequentes.

O exemplo a seguir usa um filtro e uma ordem de classificação no campo de classificação (a classificação é filtrável e classificável) porque é mais fácil ver os efeitos da paginação nos resultados classificados. Em uma consulta de pesquisa completa regular, as correspondências principais são classificadas e paginadas por @search.score.

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
{
    "search": "*",
    "filter": "Rating gt 4",
    "select": "HotelName, Rating",
    "orderby": "Rating desc",
    "top": "5",
    "count": true
}

A consulta localiza 21 documentos correspondentes, mas como você especificou top, a resposta retorna apenas as cinco principais correspondências, com classificações começando em 4,9 e terminando em 4,7 com "senhora do Lago B & B".

Para obter os próximos 5, ignore o primeiro lote:

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
{
    "search": "*",
    "filter": "Rating gt 4",
    "select": "HotelName, Rating",
    "orderby": "Rating desc",
    "top": "5",
    "skip": "5",
    "count": true
}

A resposta para o segundo lote ignora as cinco primeiras correspondências, retornando as próximas cinco, começando com "Pull'r Estalagem Motel". Para continuar com mais lotes, você deverá manter top em 5 e, em seguida, incrementar skip por 5 a cada nova solicitação (skip=5, skip=10, skip=15 e assim por diante).

"value": [
    {
        "@search.score": 1.0,
        "HotelName": "Pull'r Inn Motel",
        "Rating": 4.7
    },
    {
        "@search.score": 1.0,
        "HotelName": "Sublime Cliff Hotel",
        "Rating": 4.6
    },
    {
        "@search.score": 1.0,
        "HotelName": "Antiquity Hotel",
        "Rating": 4.5
    },
    {
        "@search.score": 1.0,
        "HotelName": "Nordick's Motel",
        "Rating": 4.5
    },
    {
        "@search.score": 1.0,
        "HotelName": "Winter Panorama Resort",
        "Rating": 4.5
    }
]

Próximas etapas

Agora que você tem alguma prática com a sintaxe de consulta básica, tente especificar 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: