Visão geral do idioma OData para $filter, $orderbye $select em Azure Cognitive Search

Este artigo fornece uma visão geral da linguagem de expressão OData utilizada em $filter, $order e $select expressões em Azure Cognitive Search. A linguagem é apresentada "de baixo para cima" começando com os elementos mais básicos. As expressões OData que pode construir num pedido de consulta variam de simples a altamente complexas, mas todas partilham elementos comuns. Os elementos partilhados incluem:

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

Uma vez que você entenda estes conceitos comuns, você pode continuar com a sintaxe de alto nível para cada expressão:

  • $filter expressões são avaliadas durante a análise de consulta, limitando a pesquisa a campos específicos ou adicionando critérios de correspondência utilizados durante as análises de índices.
  • $orderby expressões são aplicadas como um passo pós-processamento sobre um conjunto de resultados para classificar os documentos que são devolvidos.
  • $select expressões determinam quais os campos de documentos incluídos no conjunto de resultados.

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

Nota

A terminologia em Azure Cognitive Search difere da norma OData de algumas maneiras. O que chamamos de campo em Azure Cognitive Search é chamado de propriedade em OData, e similarmente para caminho de campo versus caminho de propriedade. Um índice que contém documentos em Azure Cognitive Search é referido de forma mais geral no OData como um conjunto de entidades que contém entidades. A terminologia Azure Cognitive Search é utilizada ao longo desta referência.

Caminhos de campo

O seguinte EBNF (Formulário Backus-Naur Alargado) define a gramática dos caminhos de campo.

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

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

Está também disponível um diagrama de sintaxe interativo:

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

Um identificador pode referir-se ao nome de um campo, ou a uma variável de alcance no contexto de uma expressão de recolha (any ou all) num filtro. Uma variável de gama é como uma variável de loop que representa o elemento atual da coleção. Para coleções complexas, esta variável representa um objeto, razão pela qual você pode usar caminhos de campo para se referir a subcampos da variável. Isto é análogo à notação de pontos em muitas línguas de programação.

Exemplos de percursos de campo são mostrados na tabela seguinte:

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

O significado de um caminho de campo difere dependendo do contexto. Nos filtros, um caminho de campo refere-se ao valor de uma única instância de um campo no documento atual. Em outros contextos, como $orderby, $select ou em busca de campo na sintaxe lucene completa, um caminho de campo refere-se ao próprio campo. Esta diferença tem algumas consequências na forma como utiliza caminhos de campo em filtros.

Considere o caminho Address/Citydo campo. Num filtro, isto refere-se a uma única cidade para o documento atual, como "São Francisco". Em contraste, Rooms/Type refere-se ao Type subcampo para muitos quartos (como "standard" para o primeiro quarto, "deluxe" para o segundo quarto, e assim por diante). Uma vez Rooms/Type que não se refere a um único caso do subcampo Type, não pode ser usado diretamente num filtro. Em vez disso, para filtrar no tipo de quarto, você usaria uma expressão lambda com uma variável de gama, como esta:

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

Neste exemplo, a variável room de alcance aparece no caminho de room/Type campo. Desta forma, room/Type refere-se ao tipo de sala atual no documento atual. Este é um único exemplo do Type subcampo, para que possa ser usado diretamente no filtro.

Usando caminhos de campo

Os caminhos de campo são usados em muitos parâmetros do Azure Cognitive Search REST APIs. A tabela que se segue lista todos os locais onde podem ser utilizados, além de quaisquer restrições à sua utilização:

API Nome do parâmetro Restrições
Criar ou Atualizar Índice suggesters/sourceFields Nenhuma
Criar ou Atualizar Índice scoringProfiles/text/weights Só pode referir-se a campos pesjáveis
Criar ou Atualizar Índice scoringProfiles/functions/fieldName Só pode referir-se a campos filtrados
Pesquisa search quando queryType é full Só pode referir-se a campos pesjáveis
Pesquisa facet Só pode se referir a campos facetais
Pesquisa highlight Só pode referir-se a campos pesjáveis
Pesquisa searchFields Só pode referir-se a campos pesjáveis
Sugerir e Autocompleto searchFields Só pode se referir a campos que fazem parte de um sugestivo
Pesquisar, Sugerir e Autocomplete $filter Só pode referir-se a campos filtrados
Pesquisar e Sugerir $orderby Só pode se referir a campos ordenados
Pesquisar, Sugerir e Procurar $select Só pode referir-se a campos recuperáveis

Constantes

As constantes no OData são valores literais de um determinado modelo de dados da entidade (EDM). Consulte os tipos de dados suportados para obter uma lista de tipos suportados em Azure Cognitive Search. As constantes dos tipos de recolha não são suportadas.

A tabela a seguir apresenta exemplos de constantes para cada um dos tipos de dados suportados por Azure Cognitive Search:

Tipo de dados Exemplo 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'

Escapando de personagens especiais em constantes de cordas

As constantes de cordas no OData são delimitadas por citações únicas. Se precisar de construir uma consulta com uma constante de corda que possa conter citações individuais, pode escapar às citações incorporadas duplicando-as.

Por exemplo, uma frase com um apóstrofo nãoformado como "O carro de Alice" seria representada no OData como a constante 'Alice''s car'de cordas .

Importante

Ao construir filtros programáticamente, é importante lembrar-se de escapar às constantes de cordas que vêm da entrada do utilizador. Isto é para mitigar a possibilidade de ataques de injeção, especialmente quando se utilizam filtros para implementar aparas de segurança.

Sintaxe de constantes

O seguinte EBNF (Formulário Backus-Naur Alargado) define a gramática para a maioria das constantes mostradas na tabela acima. A gramática para tipos geo-espaciais pode ser encontrada em funções geo-espaciais OData em Azure Cognitive 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'

Está também disponível um diagrama de sintaxe interativo:

Construindo expressões de caminhos de campo e constantes

Os caminhos de campo e as constantes são a parte mais básica de uma expressão OData, mas já são expressões completas. Na verdade, o parâmetro $select em Azure Cognitive Search não passa de uma lista separada por vírgulas de caminhos de campo, e $orderby não é muito mais complicado do que $select. Se por acaso tiver um campo de tipo Edm.Boolean no seu índice, pode até escrever um filtro que não passa do caminho desse campo. As constantes true e false são igualmente filtros válidos.

No entanto, a maior parte do tempo você precisará de expressões mais complexas que se referem a mais de um campo e constante. Estas expressões são construídas de diferentes formas dependendo do parâmetro.

O seguinte EBNF (Formulário Backus-Naur Alargado) define a gramática para os parâmetros $filter, $orderby e $select . Estas são construídas a partir de expressões mais simples que se referem a caminhos de campo e constantes:

filter_expression ::= boolean_expression

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

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

Está também disponível um diagrama de sintaxe interativo:

Passos seguintes

Os parâmetros $orderby e $select são ambas listas separadas por vírgulas de expressões mais simples. O parâmetro $filter é uma expressão booleana que é composta por subexpressões mais simples. Estas subexpressões são combinadas com operadores lógicos como andoperadores orde comparação como, enot, por exemplo, operadores de comparação como, e assim por diante, e operadores de recolha comoany e all. .eqltgt

Os parâmetros $filter, $orderby e $select são explorados mais detalhadamente nos seguintes artigos: