Exemplos de consultas de pesquisa "simples" no Azure AI Search

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

Nota

Uma sintaxe de consulta alternativa é Full Lucene, suportando estruturas de consulta mais complexas, como pesquisa difusa e curinga. Para obter mais informações e exemplos, consulte Usar a sintaxe Lucene completa.

Í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": "simple",
    "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 "simple" é o padrão e pode ser omitido, mas é incluído para reforçar ainda mais que os exemplos de consulta neste artigo são expressos na sintaxe simples.

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

A pesquisa de texto completo pode ser qualquer número de termos independentes ou frases entre aspas, com ou sem operadores booleanos.

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 por palavra-chave composta por termos ou frases importantes tende a funcionar melhor. Os campos de cadeia de caracteres passam por análise de texto durante a indexação e consulta, descartando palavras não essenciais como "o", "e", "ele". Para ver como uma cadeia de caracteres de consulta é tokenizada no índice, passe a cadeia de caracteres em uma chamada Analisar 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ê preferir a precisão, onde todas as partes da cadeia de caracteres devem ser correspondidas, altere searchMode para "all". Experimente a consulta acima de ambas as maneiras para ver como o searchMode altera o resultado.

A resposta para a consulta "spa piscina + aeroporto" deve ser semelhante ao exemplo a seguir, cortado para brevidade.

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

Observe a pontuação da pesquisa na resposta. Este é o placar de relevância da partida. Por padrão, um serviço de pesquisa retorna as 50 melhores 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 foi pesquisa de texto completo, ou porque nenhum critério foi fornecido. Por exemplo, em uma pesquisa vazia (search=*), as linhas voltam em ordem arbitrária. Ao incluir critérios reais, você verá as pontuações de pesquisa evoluirem para valores significativos.

Exemplo 2: Procurar por ID

Ao retornar os 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 Documento de Pesquisa passando a ID do documento.

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

Todos os documentos têm um identificador único. Se você estiver usando o portal, selecione o índice na guia Índices e, em seguida, examine as definições de campo para determinar qual campo é a chave. Usando REST, a chamada Get Index retorna a definição de í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 de í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 texto

A sintaxe de filtro é uma expressão OData que você pode usar sozinha ou com search. Usado em conjunto, filter é aplicado primeiro a todo o índice e, em seguida, a pesquisa é realizada nos resultados do filtro. Por conseguinte, os filtros podem ser uma técnica útil para melhorar o desempenho de consultas, uma vez que reduzem o conjunto de documentos necessários à consulta de pesquisa para processamento.

Os filtros podem ser definidos em qualquer campo marcado como filterable na definição do índice. Para hotels-sample-index, os campos filtráveis incluem Categoria, Tags, EstacionamentoIncluído, Classificação e a maioria dos campos 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", e que incluem os termos "arte" ou "passeios". Neste 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. Esta expressão de filtro usa um curinga gratuito para selecionar comodidades, incluindo Wi-Fi 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 gratuitas. Observe que a pontuação da pesquisa é um "1.0" uniforme ao longo dos resultados. Isso ocorre porque a expressão de pesquisa é nula ou vazia, resultando em correspondências de filtro literais, mas nenhuma pesquisa de texto completo. As pontuações de relevância só são devolvidas na pesquisa de texto completo. Se estiver a utilizar filtros sem searcho , certifique-se de que tem campos classificáveis suficientes para poder controlar a classificação da 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 intervalo é suportada através de expressões de filtros 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 os dados de cadeia de caracteres em campos de cadeia de caracteres. Os dados numéricos em campos de cadeia de caracteres não são adequados para intervalos porque as cadeias 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=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, cortado 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, cortado para brevidade. Neste exemplo, não é possível classificar por StateProvince porque o campo não é atribuído como "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 índice de amostra de hotéis inclui um campo Localização com coordenadas de latitude e longitude. Este exemplo usa a função geo.distance que filtra documentos dentro da circunferência de um ponto de partida, até uma distância arbitrária (em quilômetros) que você fornece. Você pode ajustar o último valor na consulta (10) para reduzir ou ampliar a área de 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 a esta consulta devolve todos os hotéis a uma distância de 10 km 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: Booleanos com searchMode

A sintaxe simples suporta operadores booleanos na forma de caracteres (+, -, |) para suportar a lógica de consulta E, OU e NÃO. A pesquisa booleana se comporta como você poderia esperar, com algumas exceções dignas de nota.

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

No contexto de uma pesquisa booleana, o padrão "searchMode": "any" pode ser confuso se você estiver empilhando uma consulta com vários operadores e obtendo resultados mais amplos em vez de mais restritos. Isto é particularmente verdadeiro com NOT, onde os resultados incluem todos os documentos "que não contêm" um termo ou frase específica.

O exemplo a seguir fornece uma ilustração. Executando a seguinte consulta com searchMode (qualquer), 42 documentos são retornados: 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á espaço entre o operador booleano (-) 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
}

Mudar para "searchMode": "all" impor um efeito cumulativo sobre os critérios e retorna um conjunto de resultados menor (7 correspondências) composto por documentos contendo o termo "restaurante", menos aqueles que contêm a frase "ar condicionado".

A resposta para esta consulta agora seria semelhante ao exemplo a seguir, cortado 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: Resultados de paginação

Em 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 resultados de pesquisa na forma de parâmetros de paginação que permitem agrupar o número de resultados que aparecem em qualquer página.

Por padrão, um serviço de pesquisa retorna as 50 principais correspondências. 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 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 principais correspondências 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 encontra 21 documentos correspondentes, mas como você especificou top, a resposta retorna apenas as cinco melhores 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, pule 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 pula as cinco primeiras partidas, retornando as próximas cinco, começando com "Pull'r Inn Motel". Para continuar com mais lotes, você deve manter top em 5 e, em seguida, incrementar skip em 5 em 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óximos passos

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