Compartilhar via


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 de correspondências difusas. Para obter mais informações, confira Exemplos de sintaxe de pesquisa completa do Lucene.

Í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 em Início rápido: criar um índice de pesquisa no portal do Azure.

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=2024-07-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
}
  • search definido como * é uma consulta não especificada, equivalente a uma pesquisa nula ou 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 simple é 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=2024-07-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 recall. Se você quiser mais recall, use o valor padrão any, 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 all. Experimente a consulta acima de duas maneiras para ver como o searchMode altera o resultado.

A resposta para a consulta spa com piscina + aeroporto deve ser semelhante ao exemplo a seguir, recortada para ser breve.

"@odata.count": 4,
"value": [
{
    "@search.score": 6.090657,
    "HotelId": "12",
    "HotelName": "Winter Panorama Resort",
    "Description": "Plenty of great skiing, outdoor ice skating, sleigh rides, tubing and snow biking. Yoga, group exercise classes and outdoor hockey are available year-round, plus numerous options for shopping as well as great spa services. Newly-renovated with large rooms, free 24-hr airport shuttle & a new restaurant. Rooms/suites offer mini-fridges & 49-inch HDTVs.",
    "Category": "Resort and Spa"
},
{
    "@search.score": 4.314683,
    "HotelId": "21",
    "HotelName": "Good Business Hotel",
    "Description": "1 Mile from the airport. Free WiFi, Outdoor Pool, Complimentary Airport Shuttle, 6 miles from Lake Lanier & 10 miles from downtown. Our business center includes printers, a copy machine, fax, and a work area.",
    "Category": "Suite"
},
{
    "@search.score": 3.575948,
    "HotelId": "27",
    "HotelName": "Starlight Suites",
    "Description": "Complimentary Airport Shuttle & WiFi. Book Now and save - Spacious All Suite Hotel, Indoor Outdoor Pool, Fitness Center, Florida Green certified, Complimentary Coffee, HDTV",
    "Category": "Suite"
},
{
    "@search.score": 2.6926985,
    "HotelId": "25",
    "HotelName": "Waterfront 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": "Suite"
}
]

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 apenas um documento usando Obter Documento, passando a ID do documento.

GET /indexes/hotels-sample-index/docs/41?api-version=2024-07-01

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

A resposta para a consulta anterior 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": "Windy Ocean Motel",
    "Description": "Oceanfront hotel overlooking the beach features rooms with a private balcony and 2 indoor and outdoor pools. Inspired by the natural beauty of the island, each room includes an original painting of local scenes by the owner. Rooms include a mini fridge, Keurig coffee maker, and flatscreen TV. Various shops and art entertainment are on the boardwalk, just steps away.",
    "Description_fr": "Cet hôtel en bord de mer donnant sur la plage propose des chambres dotées d'un balcon privé et de 2 piscines intérieure et extérieure. Inspiré par la beauté naturelle de l'île, chaque chambre comprend une peinture originale de scènes locales par le propriétaire. Les chambres comprennent un mini-réfrigérateur, une cafetière Keurig et une télévision à écran plat. Divers magasins et divertissements artistiques se trouvent sur la promenade, à quelques pas.",
    "Category": "Suite",
    "Tags": [
    "pool",
    "air conditioning",
    "bar"
    ],
    "ParkingIncluded": true,
    "LastRenovationDate": "2021-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. Quando usado em conjunto na mesma solicitação, o filter é aplicado primeiro ao índice inteiro e, em seguida, a pesquisa search é 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=2024-07-01
{
    "search": "art tours",
    "queryType": "simple",
    "filter": "Category eq 'Boutique'",
    "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 Resort e Spa, que incluem os termos arte ou passeios. Nesse caso, há apenas uma correspondência.

"value": [
{
    "@search.score": 1.2814453,
    "HotelId": "2",
    "HotelName": "Old Century Hotel",
    "Description": "The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts. The hotel also regularly hosts events like wine tastings, beer dinners, and live music.",
    "Category": "Boutique"
}
]

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=2024-07-01
  {
    "search": "",
    "filter": "search.ismatch('free*', 'Tags', 'full', 'any')",
    "select": "HotelName, Tags, Description",
    "count": true
  }

A resposta para a consulta acima corresponde a 27 hotéis que oferecem comodidades gratuitas. Observe que a pontuação de pesquisa é um 1 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": 27,
  "value": [
    {
      "@search.score": 1,
      "HotelName": "Country Residence Hotel",
      "Description": "All of the suites feature full-sized kitchens stocked with cookware, separate living and sleeping areas and sofa beds. Some of the larger rooms have fireplaces and patios or balconies. Experience real country hospitality in the heart of bustling Nashville. The most vibrant music scene in the world is just outside your front door.",
      "Tags": [
        "laundry service",
        "restaurant",
        "free parking"
      ]
    },
    {
      "@search.score": 1,
      "HotelName": "Downtown Mix Hotel",
      "Description": "Mix and mingle in the heart of the city. Shop and dine, mix and mingle in the heart of downtown, where fab lake views unite with a cheeky design.",
      "Tags": [
        "air conditioning",
        "laundry service",
        "free wifi"
      ]
    },
    {
      "@search.score": 1,
      "HotelName": "Starlight Suites",
      "Description": "Complimentary Airport Shuttle & WiFi. Book Now and save - Spacious All Suite Hotel, Indoor Outdoor Pool, Fitness Center, Florida Green certified, Complimentary Coffee, HDTV",
      "Tags": [
        "pool",
        "coffee in lobby",
        "free wifi"
      ]
    },
. . .

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 é Rating.

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-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, recortada para brevidade.

"@odata.count": 27,
"value": [
{
    "@search.score": 1,
    "HotelId": "22",
    "HotelName": "Lion's Den Inn",
    "Rating": 3.9
},
{
    "@search.score": 1,
    "HotelId": "25",
    "HotelName": "Waterfront Scottish Inn",
    "Rating": 3.8
},
{
    "@search.score": 1,
    "HotelId": "2",
    "HotelName": "Old Century Hotel",
    "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=2024-07-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 a seguir, recortada 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,
      "HotelId": "39",
      "HotelName": "White Mountain Lodge & Suites",
      "Address": {
        "StateProvince": "CO"
      }
    },
    {
      "@search.score": 1,
      "HotelId": "9",
      "HotelName": "Smile Up Hotel",
      "Address": {
        "StateProvince": "CA "
      }
    },
    {
      "@search.score": 1,
      "HotelId": "7",
      "HotelName": "Roach Motel",
      "Address": {
        "StateProvince": "CA "
      }
    },
    {
      "@search.score": 1,
      "HotelId": "34",
      "HotelName": "Lakefront Captain Inn",
      "Address": {
        "StateProvince": "CT"
      }
    },
    {
      "@search.score": 1,
      "HotelId": "37",
      "HotelName": "Campus Commander Hotel",
      "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=2024-07-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 quilômetros das coordenadas fornecidas:

{
  "@odata.count": 3,
  "value": [
    {
      "@search.score": 1,
      "HotelId": "45",
      "HotelName": "Happy Lake Resort & Restaurant",
      "Address": {
        "City": "Seattle",
        "StateProvince": "WA"
      }
    },
    {
      "@search.score": 1,
      "HotelId": "24",
      "HotelName": "Uptown Chic Hotel",
      "Address": {
        "City": "Seattle",
        "StateProvince": "WA"
      }
    },
    {
      "@search.score": 1,
      "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 à lógica de consulta de AND, OR, e NOT. A pesquisa booliana se comporta como você pode esperar, com algumas exceções notáveis.

Em uma pesquisa booliana, considere adicionar o parâmetro searchMode como um mecanismo para influenciar a precisão e o recall. Os valores válidos incluem "searchMode": "any", que favorece o recall (um documento que atenda a qualquer um dos critérios é considerado uma correspondência) e "searchMode": "all", que favorece a precisão de favorecimento (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 NOT, em que os resultados incluem todos os documentos que não contêm um termo ou frase específico.

O exemplo a seguir ilustra esse cenário. A consulta procura correspondências no restaurante que excluem a frase ar condicionado. A execução da consulta a seguir com searchMode (any) retorna 43 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. As aspas são com escape (\").

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-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 (sete 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, recortada para brevidade.

{
  "@odata.count": 14,
  "value": [
    {
      "@search.score": 3.1383743,
      "HotelId": "18",
      "HotelName": "Ocean Water Resort & Spa",
      "Tags": [
        "view",
        "pool",
        "restaurant"
      ]
    },
    {
      "@search.score": 2.028083,
      "HotelId": "22",
      "HotelName": "Lion's Den Inn",
      "Tags": [
        "laundry service",
        "free wifi",
        "restaurant"
      ]
    },
    {
      "@search.score": 2.028083,
      "HotelId": "34",
      "HotelName": "Lakefront Captain Inn",
      "Tags": [
        "restaurant",
        "laundry service",
        "coffee in lobby"
      ]
    },
...

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 Rating (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=2024-07-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 Pousada Lakeside.

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

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-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 Inn Motel. Para continuar com mais lotes, você deverá manter top em cinco e, em seguida, incrementar skip por cinco a cada nova solicitação (skip=5, skip=10, skip=15 e assim por diante).

{
  "@odata.count": 21,
  "value": [
    {
      "@search.score": 1,
      "HotelName": "Head Wind Resort",
      "Rating": 4.7
    },
    {
      "@search.score": 1,
      "HotelName": "Sublime Palace Hotel",
      "Rating": 4.6
    },
    {
      "@search.score": 1,
      "HotelName": "City Skyline Antiquity Hotel",
      "Rating": 4.5
    },
    {
      "@search.score": 1,
      "HotelName": "Nordick's Valley Motel",
      "Rating": 4.5
    },
    {
      "@search.score": 1,
      "HotelName": "Winter Panorama Resort",
      "Rating": 4.5
    }
  ]
}

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: