Informazioni di riferimento sulla sintassi delle espressioni OData per Ricerca di intelligenza artificiale di Azure

Ricerca di intelligenza artificiale di Azure usa espressioni OData come parametri in tutta l'API. In genere, le espressioni OData vengono usate per i $orderby parametri e $filter . Queste espressioni possono essere complesse, contenenti più clausole, funzioni e operatori. Tuttavia, anche semplici espressioni OData come i percorsi delle proprietà vengono usate in molte parti dell'API REST di Ricerca intelligenza artificiale di Azure. Ad esempio, le espressioni di percorso vengono usate per fare riferimento a sottocampi di campi complessi ovunque nell'API, ad esempio quando si elencano campi secondari in un suggerimento, una funzione di assegnazione dei punteggi, il $select parametro o anche la ricerca campiata nelle query Lucene.

Questo articolo descrive tutte queste forme di espressioni OData usando una grammatica formale. È anche disponibile un diagramma interattivo per esplorare visivamente la grammatica.

Grammatica formale

È possibile descrivere il sottoinsieme del linguaggio OData supportato da Ricerca di intelligenza artificiale di Azure usando una grammatica EBNF (Extended Backus-Naur Form). Le regole sono elencate "dall'alto verso il basso", a partire dalle espressioni più complesse e suddividerle in espressioni più primitive. Nella parte superiore sono riportate le regole grammaticali che corrispondono a parametri specifici dell'API REST di Ricerca intelligenza artificiale di Azure:

  • $filter, definito dalla filter_expression regola.
  • $orderby, definito dalla order_by_expression regola.
  • $select, definito dalla select_expression regola.
  • Percorsi dei campi, definiti dalla field_path regola. I percorsi dei campi vengono usati in tutta l'API. Possono fare riferimento a campi di primo livello di un indice o a campi secondari con uno o più predecessori di campi complessi.

Dopo che EBNF è un diagramma di sintassi esplorabile che consente di esplorare in modo interattivo la grammatica e le relazioni tra le regole.

/* Top-level rules */

filter_expression ::= boolean_expression

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

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

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


/* Shared base rules */

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


/* Rules for $orderby */

order_by_clause ::= (field_path | sortable_function) ('asc' | 'desc')?

sortable_function ::= geo_distance_call | 'search.score()'


/* Rules for $filter */

boolean_expression ::=
    collection_filter_expression
    | logical_expression
    | comparison_expression
    | boolean_literal
    | boolean_function_call
    | '(' boolean_expression ')'
    | variable

/* This can be a range variable in the case of a lambda, or a field path. */
variable ::= identifier | field_path

collection_filter_expression ::=
    field_path'/all(' lambda_expression ')'
    | field_path'/any(' lambda_expression ')'
    | field_path'/any()'

lambda_expression ::= identifier ':' boolean_expression

logical_expression ::=
    boolean_expression ('and' | 'or') boolean_expression
    | 'not' boolean_expression

comparison_expression ::= 
    variable_or_function comparison_operator constant | 
    constant comparison_operator variable_or_function

variable_or_function ::= variable | function_call

comparison_operator ::= 'gt' | 'lt' | 'ge' | 'le' | 'eq' | 'ne'


/* Rules for constants and literals */

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 ::= sign? 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'


/* Rules for functions */

function_call ::=
    geo_distance_call |
    boolean_function_call

geo_distance_call ::=
    'geo.distance(' variable ',' geo_point ')'
    | 'geo.distance(' geo_point ',' variable ')'

geo_point ::= "geography'POINT(" lon_lat ")'"

lon_lat ::= float_literal ' ' float_literal

boolean_function_call ::=
    geo_intersects_call |
    search_in_call |
    search_is_match_call

geo_intersects_call ::=
    'geo.intersects(' variable ',' geo_polygon ')'

/* You need at least four points to form a polygon, where the first and
last points are the same. */
geo_polygon ::=
    "geography'POLYGON((" lon_lat ',' lon_lat ',' lon_lat ',' lon_lat_list "))'"

lon_lat_list ::= lon_lat(',' lon_lat)*

search_in_call ::=
    'search.in(' variable ',' string_literal(',' string_literal)? ')'

/* Note that it is illegal to call search.ismatch or search.ismatchscoring
from inside a lambda expression. */
search_is_match_call ::=
    'search.ismatch'('scoring')?'(' search_is_match_parameters ')'

search_is_match_parameters ::=
    string_literal(',' string_literal(',' query_type ',' search_mode)?)?

query_type ::= "'full'" | "'simple'"

search_mode ::= "'any'" | "'all'"

Diagramma della sintassi

Per esplorare visivamente la grammatica del linguaggio OData supportata da Ricerca di intelligenza artificiale di Azure, provare il diagramma della sintassi interattiva:

Vedi anche