Visão geral da linguagem OData para $filter, $orderby e $select na IA do Azure Search

Este artigo mostra uma visão geral da linguagem de expressão do OData usada em expressões $filter, $order-by e $select na IA do Azure Search. A linguagem é apresentada "de baixo para cima", começando com os elementos mais básicos. As expressões OData que você pode construir em uma solicitação de consulta variam de simples a altamente complexas, mas todas elas compartilham elementos comuns. Os elementos compartilhados incluem:

  • Caminhos de campo, que se referem a campos específicos do índice.
  • Constantes, que são valores literais de um determinado tipo de dados.

Depois de entender esses conceitos comuns, você poderá continuar com a sintaxe de nível superior para cada expressão:

  • As expressões $filter são avaliadas durante a análise da consulta, restringindo a pesquisa a campos específicos ou adicionando critérios de correspondência usados durante as verificações de índice.
  • As expressões $orderby são aplicadas como etapa de pós-processamento em um conjunto de resultados para classificar os documentos retornados.
  • As expressões $select determinam quais campos de documento são incluídos no conjunto de resultados.

A sintaxe dessas expressões é distinta da sintaxe de consulta simples ou completa usada no parâmetro de pesquisa, embora haja sobreposição na sintaxe para fazer referência a campos.

Observação

A terminologia da IA do Azure Search difere da padrão do OData de algumas maneiras. O que chamamos de campo na IA do Azure Search é chamado de propriedade no OData, e caminho de campo equivale a caminho de propriedade. Um índice que contém documentos na IA do Azure Search é chamado de forma mais geral no OData como um conjunto de entidades que contém entidades. A terminologia da IA do Azure Search é usada em toda esta referência.

Caminhos de campo

O EBNF (formulário estendido Backus-Naur) a seguir define a gramática dos caminhos de campo.

field_path ::= identifier('/'identifier)*

identifier ::= [a-zA-Z_][a-zA-Z_0-9]*

Um diagrama de sintaxe interativa também está disponível:

Observação

Confira Referência de sintaxe da expressão do OData para IA do Azure Search para ver a EBNF completa.

Um caminho de campo é composto por um ou mais identificadores separados por barras. Cada identificador é uma sequência de caracteres que deve começar com uma letra ASCII ou sublinhado e conter apenas letras ASCII, dígitos ou sublinhados. As letras podem ser maiúsculas ou minúsculas.

Um identificador pode se referir ao nome de um campo ou a uma variável de intervalo no contexto de uma expressão de coleção (any ou all) em um filtro. Uma variável de intervalo é como uma variável de loop que representa o elemento atual da coleção. Para coleções complexas, essa variável representa um objeto. Por isso, você pode usar caminhos de campo para fazer referência a subcampos da variável. Isso é análogo à notação de ponto em muitas linguagens de programação.

A tabela abaixo contém exemplos de caminhos de campo:

Caminho de campo Descrição
HotelName Refere-se a um campo de nível superior do índice
Address/City Refere-se ao subcampo City de um campo complexo no índice; Address é do tipo Edm.ComplexType neste exemplo
Rooms/Type Refere-se ao subcampo Type de um campo complexo de coleção no índice; Rooms é do tipo Collection(Edm.ComplexType) neste exemplo
Stores/Address/Country Refere-se ao subcampo Country do subcampo Address de um campo de coleção complexo no índice; Stores é do tipo Collection(Edm.ComplexType), e Address é do tipo Edm.ComplexType neste exemplo
room/Type Refere-se ao subcampo Type da variável de intervalo room, por exemplo, na expressão de filtro Rooms/any(room: room/Type eq 'deluxe')
store/Address/Country Refere-se ao subcampo Country do subcampo Address da variável de intervalo store, por exemplo, na expressão de filtro, Stores/any(store: store/Address/Country eq 'Canada')

O significado de um caminho de campo difere dependendo do contexto. Em filtros, um caminho de campo refere-se ao valor de uma instância de um campo no documento atual. Em outros contextos, como $orderby, $select ou na pesquisa de campo na sintaxe Lucerne completa, um caminho de campo refere-se ao próprio campo. Essa diferença tem algumas consequências para a forma como você usa caminhos de campo em filtros.

Considere o caminho do campo Address/City. Em um filtro, isso se refere a uma cidade para o documento atual, como "San Francisco". Por outro lado, Rooms/Type se refere ao subcampo Type para vários quartos (como "padrão" no primeiro quarto, "deluxe" no segundo e assim por diante). Como o Rooms/Type não se refere a uma instância do subcampo Type, ele não pode ser usado diretamente em um filtro. Em vez disso, para filtrar o tipo de quarto, você usaria uma expressão lambda com uma variável de intervalo, desta forma:

Rooms/any(room: room/Type eq 'deluxe')

Neste exemplo, a variável de intervalo room aparece no caminho do campo room/Type. Dessa forma, room/Type refere-se ao tipo do quarto atual no documento atual. Essa é uma instância do subcampo Type, portanto, ela pode ser usada diretamente no filtro.

Usar caminhos de campo

Os caminhos de campo são usados em muitos parâmetros das APIs REST da IA do Azure Search. A seguinte tabela mostra todos os locais em que eles podem ser usados, além de eventuais restrições de uso:

API Nome do parâmetro Restrições
Criar ou Atualizar Índice suggesters/sourceFields Nenhum
Criar ou Atualizar Índice scoringProfiles/text/weights Só pode fazer referência a campos pesquisáveis
Criar ou Atualizar Índice scoringProfiles/functions/fieldName Só pode fazer referência a campos filtráveis
Pesquisa search quando queryType é full Só pode fazer referência a campos pesquisáveis
Pesquisa facet Só pode fazer referência aos campos de facetable
Pesquisa highlight Só pode fazer referência a campos pesquisáveis
Pesquisa searchFields Só pode fazer referência a campos pesquisáveis
Sugerir e Preenchimento Automático searchFields Só pode fazer referência a campos que fazem parte de um sugestor
Pesquisar, Sugerir e Preenchimento Automático $filter Só pode fazer referência a campos filtráveis
Pesquisar e Sugerir $orderby Só pode fazer referência a campos classificáveis
Pesquisar, Sugerire Pesquisar $select Só pode fazer referência a campos recuperáveis

Constantes

As constantes no OData são valores literais de um determinado tipo de EDM (Modelo de Dados de Entidade). Confira Tipos de dados com suporte para ver a lista de tipos com suporte na IA do Azure Search. As constantes de tipos de coleção não são compatíveis.

A seguinte tabela mostra exemplos de constantes para cada um dos tipos de dados com suporte pela IA do Azure Search:

Tipo de dados Exemplos de constantes
Edm.Boolean true, false
Edm.DateTimeOffset 2019-05-06T12:30:05.451Z
Edm.Double 3.14159, -1.2e7, NaN, INF, -INF
Edm.GeographyPoint geography'POINT(-122.131577 47.678581)'
Edm.GeographyPolygon geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'
Edm.Int32 123, -456
Edm.Int64 283032927235
Edm.String 'hello'

Caracteres especiais de escape em constantes de cadeia de caracteres

As constantes de cadeia de caracteres no OData são delimitadas por aspas simples. Se você precisar criar uma consulta com uma constante de cadeia de caracteres que contém aspas simples, dobre as aspas integradas para escapá-las.

Por exemplo, uma frase com um apóstrofo não formatado como "Alice's car" seria representada no OData como a constante de cadeia de caracteres 'Alice''s car'.

Importante

Ao criar filtros programaticamente, é importante lembrar-se de escapar constantes de cadeia de caracteres provenientes da entrada do usuário. Isso é para reduzir a possibilidade de ataques de injeção, especialmente ao usar filtros para implementar a remoção de segurança.

Sintaxe de constantes

O EBNF (Formulário de Backup Naus Estendido) a seguir define a gramática da maioria das constantes mostradas na tabela acima. A gramática dos tipos geoespaciais pode ser encontrada nas Funções geoespaciais do OData na IA do Azure Search.

constant ::=
    string_literal
    | date_time_offset_literal
    | integer_literal
    | float_literal
    | boolean_literal
    | 'null'

string_literal ::= "'"([^'] | "''")*"'"

date_time_offset_literal ::= date_part'T'time_part time_zone

date_part ::= year'-'month'-'day

time_part ::= hour':'minute(':'second('.'fractional_seconds)?)?

zero_to_fifty_nine ::= [0-5]digit

digit ::= [0-9]

year ::= digit digit digit digit

month ::= '0'[1-9] | '1'[0-2]

day ::= '0'[1-9] | [1-2]digit | '3'[0-1]

hour ::= [0-1]digit | '2'[0-3]

minute ::= zero_to_fifty_nine

second ::= zero_to_fifty_nine

fractional_seconds ::= integer_literal

time_zone ::= 'Z' | sign hour':'minute

sign ::= '+' | '-'

/* In practice integer literals are limited in length to the precision of
the corresponding EDM data type. */
integer_literal ::= digit+

float_literal ::=
    sign? whole_part fractional_part? exponent?
    | 'NaN'
    | '-INF'
    | 'INF'

whole_part ::= integer_literal

fractional_part ::= '.'integer_literal

exponent ::= 'e' sign? integer_literal

boolean_literal ::= 'true' | 'false'

Um diagrama de sintaxe interativa também está disponível:

Observação

Confira Referência de sintaxe da expressão do OData para IA do Azure Search para ver a EBNF completa.

Criar expressões usando caminhos de campo e constantes

Caminhos de campo e constantes são a parte mais básica de uma expressão do OData, mas elas já são próprias expressões completas. Na verdade, o parâmetro $select da IA do Azure Search nada mais é do que uma lista separada por vírgulas de caminhos de campo, e $orderBy não menos complicado do que $select. Se houver um campo do tipo Edm.Boolean no índice, você poderá até mesmo escrever um filtro que seja apenas o caminho do campo. As constantes true e false são filtros válidos da mesma forma.

No entanto, na maioria das vezes você precisará de expressões mais complexas que se refiram a mais de um campo e constante. Essas expressões são criadas de maneiras diferentes, dependendo do parâmetro.

O EBNF a seguir (Formulário Backus-Naur Estendido) define a gramática dos parâmetros $filter, $orderBye $Sslect. Eles são criados usando expressões mais simples que se referem a caminhos e constantes de campo:

filter_expression ::= boolean_expression

order_by_expression ::= order_by_clause(',' order_by_clause)*

select_expression ::= '*' | field_path(',' field_path)*

Um diagrama de sintaxe interativa também está disponível:

Observação

Confira Referência de sintaxe da expressão do OData para IA do Azure Search para ver a EBNF completa.

Próximas etapas

Os parâmetros $orderBy e $select são listas separadas por vírgulas de expressões mais simples. O parâmetro $filter é uma expressão booliana composta por subexpressãos mais simples. Essas subexpressãos são combinadas usando operadores lógicos, como and, or e not, operadores de comparação, como eq, lt, gt e assim por diante, bem como operadores de coleção, como any e all.

Os parâmetros $filter, $orderBye $select são analisados com mais detalhes nos seguintes artigos: