Partager via


Vue d’ensemble du langage OData pour $filter, $orderby et $select dans Recherche Azure AI

Cet article propose une vue d’ensemble du langage d’expression OData utilisé dans les expressions $filter, $order-byet $select pour la recherche par mot clé dans Recherche Azure AI sur des champs numériques et de chaînes (non-vectorielles).

Ce langage est présenté de « bas en haut », en commençant par les éléments de base. Les expressions OData que vous pouvez construire dans une plage de requête de requête vont de simples à très complexes, mais elles partagent toutes des éléments communs. Les éléments partagés incluent :

  • Les chemins de champs, qui font référence à des champs spécifiques de votre index.
  • Les constantes, qui sont les valeurs littérales d’un certain type de données.

Une fois que vous avez compris ces concepts courants, vous pouvez continuer avec la syntaxe de niveau supérieur pour chaque expression :

  • Les expression $filter sont évaluées lors de l’analyse de la requête, limitant la recherche à des champs spécifiques ou ajoutant des critères de correspondance utilisés lors du parcours des index.
  • Les expressions $orderby sont appliquées dans une étape de post-traitement sur un jeu de résultats pour trier les documents renvoyés.
  • Les expressions $select déterminent les champs du document inclus dans le jeu de résultats.

La syntaxe de ces expressions se distingue de la syntaxe de recherche simple ou complète utilisée dans le paramètre search et ce, malgré la présence d’un certain chevauchement pour référencer les champs.

Pour obtenir des exemples dans d’autres langages tels que Python ou C#, consultez les exemples du référentiel azure-search-vector-samples.

Remarque

Dans Recherche Azure AI, la terminologie employée diffère à certains égards du langage OData standard. Ce que nous appelons champ dans Recherche Azure AI est appelé propriété dans OData, et de même, chemin de champ est appelé chemin de propriété. Un index contenant des documents dans Recherche Azure AI est appelé plus généralement jeu d’entités contenant entités dans OData. La terminologie Recherche Azure AI a été utilisée tout au long de cet article.

Chemins de champs

L’extension EBNF suivante (Extended Backus-Naur Form) définit la grammaire des chemins des champs.

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

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

Un diagramme de syntaxe interactif est également disponible :

Remarque

Consultez Informations de référence sur la syntaxe d’expression OData pour la Recherche Azure AI afin d’avoir la forme EBNF complète.

Un chemin de champ comprend un ou plusieurs identificateurs séparés par des barres obliques. Chaque identificateur correspond à une séquence de caractères qui doit commencer par une lettre ASCII ou un trait de soulignement, et contenir uniquement des lettres ASCII, des chiffres ou des traits de soulignement. Il peut s'agir de lettres majuscules ou minuscules.

Un identificateur peut faire référence à un nom de champ ou à une variable de portée dans le contexte d’une expression de collection (any ou all) au sein d'un filtre. Une variable de portée s'apparente à une variable de boucle qui représente l’élément actuel de la collection. Pour les collections complexes, cette variable représente un objet, ce qui explique pourquoi vous pouvez utiliser des chemins de champs pour faire référence aux sous-champs de la variable. Cela s'apparente à la notation par points de nombreux langages de programmation.

Des exemples de chemins de champs sont présentés dans le tableau suivant :

Chemin de champ Description
HotelName Fait référence à un champ d'index de niveau supérieur
Address/City Fait référence au sous-champ City d’un champ d’index complexe ; Address est de type Edm.ComplexType dans cet exemple
Rooms/Type Fait référence au sous-champ Type d’un champ de collection complexe ; Rooms est de type Collection(Edm.ComplexType) dans cet exemple
Stores/Address/Country Fait référence au sous-champ Country du sous-champ Address d’un champ de collection complexe ; Stores est de type Collection(Edm.ComplexType) et Address de type Edm.ComplexType dans cet exemple
room/Type Fait référence au sous-champ Type de la variable de portée room, par exemple, dans l’expression filter Rooms/any(room: room/Type eq 'deluxe')
store/Address/Country Fait référence au sous-champ Country du sous-champ Address de la variable de portée store, par exemple, dans l’expression filter Stores/any(store: store/Address/Country eq 'Canada')

La signification d’un chemin de champ diffère selon le contexte. Dans les filtres, un chemin de champ fait référence à la valeur d’une seule instance de champ dans le document actif. Dans d’autres contextes, tels que $orderby, $select, ou dans la recherche par champ de la syntaxe Lucene complète, un chemin de champ fait référence au champ à proprement parler. Cette différence n'est pas sans conséquence sur la manière d'utiliser les chemins de champs dans les filtres.

Examinez le chemin de champ Address/City. Dans un filtre, il fait référence à une seule ville pour le document actif, comme « San Francisco ». En revanche, Rooms/Type fait référence au sous-champ Type pour de nombreuses chambres (par exemple, « standard » pour la première chambre, « deluxe » pour la deuxième chambre, etc.). Rooms/Type ne faisant pas référence à une instance unique du sous-champ Type, il ne peut pas être utilisé directement dans un filtre. Au lieu de cela, pour filtrer sur un type de chambre, vous devez utiliser une expression lambda avec une variable de portée, telle que :

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

Dans cet exemple, la variable de portée room s’affiche dans le chemin de champ room/Type. Ainsi, room/Type fait référence au type de chambre actuel dans le document actif. Il s’agit d’une instance unique du sous-champ Type, et il peut donc être utilisé directement dans le filtre.

Utilisation des chemins de champs

Les chemins de champs sont utilisés dans de nombreux paramètres des API REST de Recherche Azure AI. Le tableau ci-dessous répertorie tous les emplacements où ils peuvent être utilisés, ainsi que les restrictions qui s'y rapportent :

API Nom du paramètre Restrictions
Créer ou Mettre à jour l'index suggesters/sourceFields Aucun(e)
Créer ou Mettre à jour l'index scoringProfiles/text/weights Peut uniquement faire référence à des champs pouvant faire l'objet d'une recherche
Créer ou Mettre à jour l'index scoringProfiles/functions/fieldName Peuvent uniquement faire référence à des champs filtrables
Search search quand queryType est full Peut uniquement faire référence à des champs pouvant faire l'objet d'une recherche
Search facet Peut uniquement faire référence à des champs à choix multiples
Search highlight Peut uniquement faire référence à des champs pouvant faire l'objet d'une recherche
Search searchFields Peut uniquement faire référence à des champs pouvant faire l'objet d'une recherche
Suggest et Autocomplete searchFields Peuvent uniquement faire référence à des champs appartenant à un suggesteur
Search, Suggest et Autocomplete $filter Peuvent uniquement faire référence à des champs filtrables
Search et Suggest $orderby Peuvent uniquement faire référence à des champs triables
Search, Suggest et Lookup $select Peuvent uniquement faire référence à des champs récupérables

Constantes

Dans OData, les constantes correspondent aux valeurs littérales d'un type Entity Data Model (EDM) donné. Pour obtenir la liste des types pris en charge dans Recherche Azure AI, consultez Types de données pris en charge. Les constantes des types de collection ne sont pas prises en charge.

Le tableau suivant présente des exemples de constantes pour chacun des types de données non vectorielles qui prennent en charge les expressions OData :

Type de données Exemples 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'

Échappement des caractères spéciaux dans les constantes de chaîne

Les constantes de chaîne dans OData sont délimitées par des guillemets simples. Si vous devez construire une requête avec une constante de chaîne susceptible de contenir des guillemets simples, vous pouvez placer les guillemets incorporés dans une séquence d’échappement en les doublant.

Par exemple, une expression avec une apostrophe non mise en forme comme « voiture d'Alice » est représentée dans OData en tant que constante de chaîne 'Alice''s car'.

Important

Quand vous construisez des filtres programmatiquement, pensez à échapper les constantes de chaîne qui proviennent d’une entrée utilisateur. Vous pouvez ainsi limiter les risques d’attaques par injection, en particulier lors de l’utilisation de filtres pour implémenter un filtrage de sécurité.

Syntaxe des constantes

L’extension EBNF suivante (Extended Backus-Naur Form) définit la grammaire de la plupart des constantes présentées dans le tableau ci-dessus. La grammaire correspondant aux types géospatiaux est disponible dans Fonctions géospatiales OData dans Recherche Azure AI.

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'

Un diagramme de syntaxe interactif est également disponible :

Remarque

Consultez Informations de référence sur la syntaxe d’expression OData pour la Recherche Azure AI afin d’avoir la forme EBNF complète.

Création d’expressions à partir de chemins de champs et de constantes

Les chemins de champs et les constantes constituent les éléments de base d'une expression OData, mais elles n'en restent pas moins des expressions complètes. Dans Recherche Azure AI, le paramètre $select n’est en fait rien d’autre qu’une liste de chemins de champs séparés par des virgules, et $orderby n’est pas plus compliqué que $select. Si votre index contient un champ de type Edm.Boolean, vous pouvez même écrire un filtre qui n’est rien d’autre que le chemin de ce champ. Les constantes true et false sont également des filtres valides.

Toutefois, il est plus courant d’avoir des expressions complexes qui font référence à plusieurs champs et constantes. Ces expressions sont générées de différentes manières selon le paramètre.

L’extension EBNF suivante (Extended Backus-Naur Form) définit la grammaire des paramètres $filter, $orderby et $select. Ils sont conçus à partir d'expressions plus simples faisant référence à des chemins de champs et constantes :

filter_expression ::= boolean_expression

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

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

Un diagramme de syntaxe interactif est également disponible :

Remarque

Consultez Informations de référence sur la syntaxe d’expression OData pour la Recherche Azure AI afin d’avoir la forme EBNF complète.

Étapes suivantes

Les paramètres $orderby et $select correspondent à des listes d'expressions plus simples séparées par des virgules. Le paramètre $filter est une expression conditionnelle composée de sous-expressions plus simples. Ces sous-expressions sont combinées à l’aide d’opérateurs logiques tels que and, or et not, d’opérateurs de comparaison tels que eq, lt, gt, et ainsi de suite, et d’opérateurs de collection tels que any et all.

Les paramètres $filter, $orderby et $select sont abordés plus en détail dans les articles suivants :