Condividi tramite


Panoramica del linguaggio OData per $filter, $orderby e $select in Azure AI Search

Questo articolo offre una panoramica del linguaggio di espressione OData usato nelle espressioni $filter, $order-by e $select per la ricerca di parole chiave in Azure AI Search sui campi numerici e stringa (non vettoriali).

Il linguaggio viene presentato dal basso in alto, a partire dagli elementi più basici. Le espressioni OData che è possibile costruire in una query richiedono un intervallo da semplice ad alta complessità, ma condividono tutti elementi comuni. Gli elementi condivisi includono:

  • Percorsi dei campi, che fanno riferimento a campi specifici dell'indice.
  • Costanti, che sono valori letterali di un determinato tipo di dati.

Dopo aver compreso questi concetti comuni, è possibile continuare con la sintassi di primo livello per ogni espressione:

  • Le espressioni $filter vengono valutate durante l'analisi della query, vincolando la ricerca a campi specifici o aggiungendo criteri di corrispondenza durante le analisi dell'indice.
  • Le espressioni $orderby vengono applicate come passaggio di post-elaborazione su un set di risultati per ordinare i documenti restituiti.
  • Le espressioni $select determinano i campi del documento inclusi nel set di risultati.

La sintassi di queste espressioni è distinta dalla sintassi di query semplice o completa usata nel parametro di ricerca, anche se nella sintassi per fare riferimento ai campi è presente una certa sovrapposizione.

Per esempi in altri linguaggi, ad esempio Python o C#, vedere gli esempi nel repository azure-search-vector-samples.

Nota

La terminologia in Azure AI Search differisce dallo standard OData in vari modi. Quello che viene chiamato campo in Azure AI Search è una proprietà in OData e ciò avviene analogamente per percorso di campo rispetto al percorso di proprietà. Un indice contenente documenti in Azure AI Search viene in genere indicato in OData come set di entità contenente entità. La terminologia di Azure AI Search viene usata in questo riferimento.

Percorsi dei campi

Il seguente EBNF (Extended Backus-Naur Form) definisce la grammatica dei percorsi dei campi.

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

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

È disponibile anche un diagramma di sintassi interattivo:

Un percorso di campo è composto da uno o più identificatori separati da barre. Ogni identificatore è una sequenza di caratteri che deve iniziare con una lettera o un carattere di sottolineatura ASCII e contenere solo lettere, cifre o caratteri di sottolineatura ASCII. Le lettere possono essere maiuscole o minuscole.

Un identificatore può fare riferimento al nome di un campo o a una variabile di intervallo nel contesto di un'espressione di raccolta (any o all) in un filtro. Una variabile di intervallo è simile a una variabile di ciclo che rappresenta l'elemento corrente della raccolta. Per le raccolte complesse, tale variabile rappresenta un oggetto, motivo per cui è possibile usare i percorsi dei campi per fare riferimento ai sottocampi della variabile. La situazione è analoga alla notazione con il punto di molti linguaggi di programmazione.

Nella tabella seguente sono riportati alcuni esempi di percorsi di campi:

Percorso di campo Descrizione
HotelName Fa riferimento a un campo di primo livello dell'indice
Address/City Fa riferimento al sottocampo City di un campo complesso nell'indice; Address è di tipo Edm.ComplexType in questo esempio
Rooms/Type Fa riferimento al sottocampo Type di un campo di raccolta complesso nell'indice; Rooms è di tipo Collection(Edm.ComplexType) in questo esempio
Stores/Address/Country Fa riferimento al sottocampo Country del sottocampo Address di un campo di raccolta complesso nell'indice; Stores è di tipo Collection(Edm.ComplexType) e Address è di tipo Edm.ComplexType in questo esempio
room/Type Fa riferimento al sottocampo Type della variabile di intervallo room, ad esempio nell'espressione di filtro Rooms/any(room: room/Type eq 'deluxe')
store/Address/Country Fa riferimento al sottocampo Country del sottocampo Address della variabile di intervallo store, ad esempio nell'espressione di filtro Stores/any(store: store/Address/Country eq 'Canada')

Il significato di un percorso di campo varia a seconda del contesto. Nei filtri, un percorso di campo fa riferimento al valore di una singola istanza di un campo nel documento corrente. In altri contesti, ad esempio $orderby, $select o nella ricerca con campi nella sintassi Lucene completa, un percorso di campo fa riferimento al campo stesso. Questa differenza ha alcune conseguenze nell'uso dei percorsi dei campi nei filtri.

Si consideri il percorso di campo Address/City. In un filtro, si riferisce a una sola città per il documento corrente, ad esempio "San Francisco". Al contrario, Rooms/Type si riferisce al sottocampo Type per molte camere (come "standard" per la prima camera, "deluxe" per la seconda camera e così via). Poiché Rooms/Type non fa riferimento a una istanza singola del sottocampo Type, non può essere usata direttamente in un filtro. Per filtrare in base al tipo di camera, è invece necessario usare un'espressione lambda con una variabile di intervallo, come illustrato di seguito:

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

In questo esempio la variabile di intervallo room viene visualizzata nel percorso di campo room/Type. In questo modo, room/Type fa riferimento al tipo di camera corrente nel documento corrente. Si tratta di una singola istanza del sottocampo Type, quindi può essere usata direttamente nel filtro.

Uso dei percorsi di campo

I percorsi di campo vengono usati in molti parametri delle API REST di Azure AI Search. Nella tabella seguente sono elencate tutte le posizioni in cui possono essere usati, oltre a eventuali restrizioni relative all'utilizzo:

API Nome parametro Restrizioni
Creare o aggiornare l'indice suggesters/sourceFields None
Creare o aggiornare l'indice scoringProfiles/text/weights Può fare riferimento solo a campi ricercabili
Creare o aggiornare l'indice scoringProfiles/functions/fieldName Può fare riferimento solo a campi filtrabili
Ricerca search quando queryType è full Può fare riferimento solo a campi ricercabili
Ricerca facet Può fare riferimento solo a campi con facet
Ricerca highlight Può fare riferimento solo a campi ricercabili
Ricerca searchFields Può fare riferimento solo a campi ricercabili
Suggerire e completare automaticamente searchFields Può fare riferimento solo ai campi che fanno parte di uno strumento suggerimenti
Cercare, Suggerire e Completare automaticamente $filter Può fare riferimento solo a campi filtrabili
Cercare e Suggerire $orderby Può fare riferimento solo a campi ordinabili
Cercare, Suggerire e Ricercare $select Può fare riferimento solo a campi recuperabili

Costanti

Le costanti in OData sono valori letterali di un tipo Entity Data Model (EDM) specificato. Vedere Tipi di dati supportati per trovare un elenco dei tipi supportati in Azure AI Search. Le costanti dei tipi di raccolte non sono supportate.

La tabella seguente mostra esempi di costanti per ognuno dei tipi di dati non vettoriali che supportano le espressioni OData:

Tipo di dati Costanti di esempio
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'

Escape di caratteri speciali nelle costanti stringa

Le costanti stringa in OData sono delimitate da virgolette singole. Se è necessario costruire una query con una costante stringa che può contenere virgolette singole, è possibile evitare le virgolette incorporate raddoppiandole.

Ad esempio, una frase con un apostrofo non formattato come "L'auto di Alice" verrebbe rappresentata in OData come costante stringa 'Alice''s car'.

Importante

Quando si creano filtri a livello di codice, è importante ricordare di usare costanti stringa di escape provenienti dall'input dell'utente. Ciò consente di attenuare la possibilità di attacchi injection, soprattutto quando si usano filtri per implementare la limitazione per motivi di sicurezza.

Sintassi delle costanti

Il seguente EBNF (Extended Backus-Naur Form) definisce la grammatica per la maggior parte delle costanti illustrate nella tabella precedente. La grammatica per i tipi geo-spaziali è reperibile in Funzioni geo-spaziali OData in Azure AI 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'

È disponibile anche un diagramma di sintassi interattivo:

Compilazione di espressioni da percorsi di campo e costanti

I percorsi di campo e le costanti sono la parte più semplice di un'espressione OData, ma sono già espressioni complete. In effetti, il parametro $select in Azure AI Search non è altro che un elenco delimitato da virgole di percorsi di campo e $orderby non è molto più complicato di $select. Se si dispone di un campo di tipo Edm.Boolean nell'indice, è anche possibile scrivere un filtro che non sia altro che il percorso di tale campo. Anche le costanti true e false sono filtri validi.

Tuttavia, è più comune avere espressioni complesse che fanno riferimento a più campi e costanti. Queste espressioni vengono compilate in modi diversi a seconda del parametro.

Il seguente EBNF (Extended Backus-Naur Form) definisce la grammatica per i parametri $filter, $orderby e $select. Si tratta di espressioni più semplici che fanno riferimento a percorsi di campo e costanti:

filter_expression ::= boolean_expression

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

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

È disponibile anche un diagramma di sintassi interattivo:

Passaggi successivi

I parametri $orderby e $select sono entrambi elenchi delimitati da virgole di espressioni più semplici. Il parametro $filter è un'espressione booleana composta da sottoespressioni più semplici. Queste sottoespressioni vengono combinate usando operatori logici come and, or e not, operatori di confronto come eq, lt, gt e così via e operatori di raccolta come any e all.

I parametri $filter, $orderbye $select vengono esaminati in modo più dettagliato negli articoli seguenti: