Overzicht van OData-taal voor $filter, $orderbyen $select in Azure AI Search

Dit artikel bevat een overzicht van de OData-expressietaal die wordt gebruikt in $filter, $order by en $select expressies in Azure AI Search. De taal wordt 'bottom-up' gepresenteerd, te beginnen met de meest elementaire elementen. De OData-expressies die u in een queryaanvraag kunt maken, variëren van eenvoudig tot zeer complex, maar ze delen allemaal algemene elementen. Gedeelde elementen zijn onder andere:

  • Veldpaden, die verwijzen naar specifieke velden van uw index.
  • Constanten, die letterlijke waarden van een bepaald gegevenstype zijn.

Zodra u deze algemene concepten begrijpt, kunt u doorgaan met de syntaxis op het hoogste niveau voor elke expressie:

  • $filter expressies worden geëvalueerd tijdens het parseren van query's, het beperken van zoekopdrachten tot specifieke velden of het toevoegen van overeenkomende criteria die tijdens indexscans worden gebruikt.
  • $orderby expressies worden toegepast als een naverwerkingsstap over een resultatenset om de documenten te sorteren die worden geretourneerd.
  • $select expressies bepalen welke documentvelden zijn opgenomen in de resultatenset.

De syntaxis van deze expressies verschilt van de eenvoudige of volledige querysyntaxis die in de zoekparameter wordt gebruikt, hoewel er enige overlap is in de syntaxis voor het verwijzen naar velden.

Notitie

Terminologie in Azure AI Search verschilt op enkele manieren van de OData-standaard . Wat we een veld in Azure AI Search noemen, wordt een eigenschap in OData genoemd en wordt ook wel veldpad versus eigenschapspad genoemd. Een index met documenten in Azure AI Search wordt doorgaans in OData aangeduid als een entiteitsset die entiteiten bevat. De Terminologie van Azure AI Search wordt in deze verwijzing gebruikt.

Veldpaden

Met het volgende EBNF-formulier (Extended Backus-Naur Form) wordt de grammatica van veldpaden gedefinieerd.

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

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

Er is ook een interactief syntaxisdiagram beschikbaar:

Een veldpad bestaat uit een of meer id's , gescheiden door slashes. Elke id is een reeks tekens die moeten beginnen met een ASCII-letter of onderstrepingsteken en alleen ASCII-letters, cijfers of onderstrepingstekens bevatten. De letters kunnen hoofdletters of kleine letters zijn.

Een id kan verwijzen naar de naam van een veld of naar een bereikvariabele in de context van een verzamelingsexpressie (any of all) in een filter. Een bereikvariabele lijkt op een lusvariabele die het huidige element van de verzameling vertegenwoordigt. Voor complexe verzamelingen vertegenwoordigt die variabele een object. Daarom kunt u veldpaden gebruiken om te verwijzen naar subvelden van de variabele. Dit is vergelijkbaar met punt notatie in veel programmeertalen.

Voorbeelden van veldpaden worden weergegeven in de volgende tabel:

Veldpad Beschrijving
HotelName Verwijst naar een veld op het hoogste niveau van de index
Address/City Verwijst naar het City subveld van een complex veld in de index; Address is van het type Edm.ComplexType in dit voorbeeld
Rooms/Type Verwijst naar het Type subveld van een complex verzamelingsveld in de index; Rooms is van het type Collection(Edm.ComplexType) in dit voorbeeld
Stores/Address/Country Verwijst naar het Country subveld van het Address subveld van een complex verzamelingsveld in de index; Stores is van het type Collection(Edm.ComplexType) en Address is van het type Edm.ComplexType in dit voorbeeld
room/Type Verwijst naar het Type subveld van de room bereikvariabele, bijvoorbeeld in de filterexpressie Rooms/any(room: room/Type eq 'deluxe')
store/Address/Country Verwijst naar het Country subveld van het Address subveld van de store bereikvariabele, bijvoorbeeld in de filterexpressie Stores/any(store: store/Address/Country eq 'Canada')

De betekenis van een veldpad verschilt afhankelijk van de context. In filters verwijst een veldpad naar de waarde van één exemplaar van een veld in het huidige document. In andere contexten, zoals $orderby, $select of zoeken in velden in de volledige Lucene-syntaxis, verwijst een veldpad naar het veld zelf. Dit verschil heeft enkele gevolgen voor het gebruik van veldpaden in filters.

Houd rekening met het veldpad Address/City. In een filter verwijst dit naar één plaats voor het huidige document, zoals 'San Francisco'. Verwijst daarentegen Rooms/Type naar het Type subveld voor veel kamers (zoals "standaard" voor de eerste kamer, "deluxe" voor de tweede kamer, enzovoort). Omdat Rooms/Type niet naar één exemplaar van het subveld Typeverwijst, kan het niet rechtstreeks in een filter worden gebruikt. Als u in plaats daarvan wilt filteren op ruimtetype, gebruikt u een lambda-expressie met een bereikvariabele, zoals deze:

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

In dit voorbeeld wordt de bereikvariabele room weergegeven in het room/Type veldpad. Op die manier room/Type verwijst u naar het type van de huidige ruimte in het huidige document. Dit is één exemplaar van het Type subveld, zodat het rechtstreeks in het filter kan worden gebruikt.

Veldpaden gebruiken

Veldpaden worden gebruikt in veel parameters van de REST API's van Azure AI Search. De volgende tabel bevat alle plaatsen waar ze kunnen worden gebruikt, plus eventuele beperkingen voor hun gebruik:

API Parameternaam Beperkingen
Index maken of bijwerken suggesters/sourceFields Geen
Index maken of bijwerken scoringProfiles/text/weights Kan alleen verwijzen naar doorzoekbare velden
Index maken of bijwerken scoringProfiles/functions/fieldName Kan alleen verwijzen naar filterbare velden
Zoeken search wanneer queryType is full Kan alleen verwijzen naar doorzoekbare velden
Zoeken facet Kan alleen verwijzen naar facetabelvelden
Zoeken highlight Kan alleen verwijzen naar doorzoekbare velden
Zoeken searchFields Kan alleen verwijzen naar doorzoekbare velden
Suggesties en automatisch aanvullen searchFields Kan alleen verwijzen naar velden die deel uitmaken van een suggestie
Zoeken, voorstellen en automatisch aanvullen $filter Kan alleen verwijzen naar filterbare velden
Zoeken en voorstellen $orderby Kan alleen verwijzen naar sorteerbare velden
Zoeken, voorstellen en opzoeken $select Kan alleen verwijzen naar ophaalbare velden

Constanten

Constanten in OData zijn letterlijke waarden van een bepaald EDM-type (Entity Data Model ). Zie Ondersteunde gegevenstypen voor een lijst met ondersteunde typen in Azure AI Search. Constanten van verzamelingstypen worden niet ondersteund.

In de volgende tabel ziet u voorbeelden van constanten voor elk van de gegevenstypen die worden ondersteund door Azure AI Search:

Gegevenstype Voorbeeldconstanten
Edm.Boolean true, false
Edm.DateTimeOffset 2019-05-06T12:30:05.451Z
Edm.Double 3.14159NaN, -1.2e7, 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'

Ontsnappen aan speciale tekens in tekenreeksconstanten

Tekenreeksconstanten in OData worden gescheiden door enkele aanhalingstekens. Als u een query wilt maken met een tekenreeksconstante die mogelijk enkele aanhalingstekens bevat, kunt u de ingesloten aanhalingstekens ontsnappen door deze te verdubbelen.

Een woordgroep met een ongeformatteerde apostrof zoals 'Alice's car' wordt bijvoorbeeld weergegeven in OData als de tekenreeksconstante 'Alice''s car'.

Belangrijk

Wanneer u filters programmatisch maakt, is het belangrijk om te onthouden dat u tekenreeksconstanten die afkomstig zijn van gebruikersinvoer, escapet. Dit is om de mogelijkheid van injectieaanvallen te beperken, met name wanneer u filters gebruikt om beveiligingsbeperkingen te implementeren.

Syntaxis van constanten

In het volgende EBNF-formulier (Extended Backus-Naur Form) wordt de grammatica gedefinieerd voor de meeste constanten die in de bovenstaande tabel worden weergegeven. De grammatica voor geo-ruimtelijke typen vindt u in geo-ruimtelijke OData-functies 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'

Er is ook een interactief syntaxisdiagram beschikbaar:

Expressies bouwen vanuit veldpaden en constanten

Veldpaden en constanten vormen het meest elementaire onderdeel van een OData-expressie, maar ze zijn al volledige expressies zelf. De parameter $select in Azure AI Search is in feite niets anders dan een door komma's gescheiden lijst met veldpaden en $orderby is niet veel ingewikkelder dan $select. Als u een veld van het type Edm.Boolean in uw index hebt, kunt u zelfs een filter schrijven dat niets anders is dan het pad van dat veld. De constanten true en false zijn eveneens geldige filters.

Meestal hebt u echter complexere expressies nodig die verwijzen naar meer dan één veld en constante. Deze expressies zijn op verschillende manieren gebouwd, afhankelijk van de parameter.

Met het volgende EBNF-formulier (Extended Backus-Naur Form) definieert u de grammatica voor de parameters $filter, $orderby en $select . Deze zijn opgebouwd uit eenvoudigere expressies die verwijzen naar veldpaden en constanten:

filter_expression ::= boolean_expression

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

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

Er is ook een interactief syntaxisdiagram beschikbaar:

Volgende stappen

De parameters $orderby en $select zijn beide door komma's gescheiden lijsten met eenvoudigere expressies. De parameter $filter is een Boole-expressie die bestaat uit eenvoudigere subexpressies. Deze subexpressies worden gecombineerd met logische operatoren zoals and, oren not, vergelijkingsoperatoren zoals eq, lt, gt, enzovoort, en verzamelingsoperatoren zoalsanyen .all

De parameters $filter, $orderby en $select worden in de volgende artikelen uitgebreider besproken: