Introducción al lenguaje de OData para las expresiones $filter
, $orderby
y $select
en Azure AI Search
En este artículo se proporciona información general sobre el lenguaje de expresiones de OData que se usa en $filter
, $order-by
, y $select
expresiones para la búsqueda de palabras clave en Azure AI Search sobre campos numéricos y de cadena (novector).
El lenguaje se presenta en sentido ascendente, empezando por los elementos más básicos. Las expresiones OData que se pueden construir en una solicitud de consulta pueden ser desde simples hasta muy complejas, pero todas comparten elementos comunes. Entre los elementos compartidos se incluyen los siguientes:
- Rutas de acceso de campo, que hacen referencia a campos específicos del índice.
- Constantes, que son valores literales de un tipo de datos determinado.
Una vez que comprenda estos conceptos comunes, puede continuar con la sintaxis de nivel superior para cada expresión:
- Las expresiones $filter se evalúan durante el análisis de la consulta y se restringe la búsqueda a campos específicos o se agregan criterios de coincidencia que se usan durante los exámenes de índice.
- Las expresiones $orderby se aplican como un paso posterior al procesamiento en un conjunto de resultados para ordenar los documentos que se devuelven.
- Las expresiones $select determinan qué campos de un documento se incluyen en el conjunto de resultados.
La sintaxis de estas expresiones es distinta de la sintaxis de consulta simple o completa que se usa en el parámetro search, aunque hay cierto solapamiento en la sintaxis de los campos de referencia.
Para obtener ejemplos en otros lenguajes, como Python o C#, consulte los ejemplos del repositorioazure-search-vector-samples.
Nota:
La terminología de Azure AI Search tiene ciertas diferencias con respecto al estándar de OData. Lo que llamamos un campo en Azure AI Search se denomina una propiedad en OData y lo mismo sucede con ruta de acceso de campo y ruta de acceso de propiedad. Un índice que contiene documentos en Azure AI Search se conoce más generalmente en OData como un conjunto de entidades que contiene entidades. En esta referencia se usará la terminología de Azure AI Search.
Rutas de acceso de campo
La siguiente EBNF (notación de Backus-Naur extendida) define la gramática de las rutas de acceso de campo:
field_path ::= identifier('/'identifier)*
identifier ::= [a-zA-Z_][a-zA-Z_0-9]*
También está disponible un diagrama de sintaxis interactivo:
Nota:
Consulte Referencia de la sintaxis de expresiones de OData para Azure AI Search para obtener la EBNF completa.
Una ruta de acceso de campo se compone de uno o varios identificadores separados por barras diagonales. Cada identificador es una secuencia de caracteres que debe comenzar con una letra ASCII o un carácter de subrayado y contener solo letras ASCII, dígitos o caracteres de subrayado. Las letras pueden ser mayúsculas o minúsculas.
Un identificador puede hacer referencia al nombre de un campo o a una variable de rango en el contexto de una expresión de colección (any
o all
) en un filtro. Una variable de rango es como una variable de bucle que representa el elemento actual de la colección. Si las colecciones son complejas, esa variable representa un objeto, que es el motivo de que pueda usar rutas de acceso de campo para hacer referencia a subcampos de la variable. Esta sintaxis es análoga a la notación de puntos de muchos lenguajes de programación.
En la tabla siguiente se muestran ejemplos de rutas de acceso de campo:
Ruta de acceso de campo | Descripción |
---|---|
HotelName |
Hace referencia a un campo de nivel superior del índice. |
Address/City |
Hace referencia al subcampo City de un campo complejo en el índice; Address es de tipo Edm.ComplexType en este ejemplo. |
Rooms/Type |
Hace referencia al subcampo Type de un campo de colección complejo en el índice; Rooms es de tipo Collection(Edm.ComplexType) en este ejemplo. |
Stores/Address/Country |
Hace referencia al subcampo Country del subcampo Address de un campo de colección complejo en el índice; Stores es de tipo Collection(Edm.ComplexType) y Address es de tipo Edm.ComplexType en este ejemplo. |
room/Type |
Hace referencia al subcampo Type de la variable de rango room , por ejemplo, en la expresión de filtro Rooms/any(room: room/Type eq 'deluxe') . |
store/Address/Country |
Hace referencia al subcampo Country del subcampo Address de la variable de rango store , por ejemplo, en la expresión de filtro Stores/any(store: store/Address/Country eq 'Canada') . |
El significado de una ruta de acceso de campo varía según el contexto. En los filtros, una ruta de acceso de campo hace referencia al valor de una única instancia de un campo en el documento actual. En otros contextos, como $orderby, $select o en la búsqueda clasificada por campos de la sintaxis completa de Lucene, una ruta de acceso de campo hace referencia al campo propiamente dicho. Esta diferencia tiene algunas consecuencias en cómo se usan las rutas de acceso de campo en los filtros.
Considere la ruta de acceso de campo Address/City
. En un filtro, esta ruta hacer referencia a una única ciudad del documento actual, como "San Francisco". En cambio, Rooms/Type
hace referencia al subcampo Type
para muchas habitaciones (por ejemplo, "standard" para la primera habitación, "deluxe" para la segunda, etc.). Puesto que Rooms/Type
no hace referencia a una única instancia del subcampo Type
, no se puede usar directamente en un filtro. Así que, para filtrar por el tipo de habitación, usaría una expresión lambda con una variable de rango, como esta:
Rooms/any(room: room/Type eq 'deluxe')
En este ejemplo, la variable de rango room
aparece en la ruta de acceso de campo room/Type
. De este modo, room/Type
hace referencia al tipo de habitación actual en el documento actual. Como es una única instancia del subcampo Type
, se puede usar directamente en el filtro.
Uso de rutas de acceso de campo
Las rutas de acceso de campo se usan muchos parámetros de las API REST de Azure AI Search. En la tabla siguiente se enumeran todos los lugares donde pueden usarse, además de las restricciones sobre su uso:
API | Nombre de parámetro | Restricciones |
---|---|---|
Create or Update Index | suggesters/sourceFields |
Ninguno |
Create or Update Index | scoringProfiles/text/weights |
Solo puede hacer referencia a campos que permiten realizar búsquedas. |
Create or Update Index | scoringProfiles/functions/fieldName |
Solo puede hacer referencia a campos filtrables. |
Buscar | search cuando queryType es full |
Solo puede hacer referencia a campos que permiten realizar búsquedas. |
Buscar | facet |
Solo puede hacer referencia a campos clasificables |
Buscar | highlight |
Solo puede hacer referencia a campos que permiten realizar búsquedas. |
Buscar | searchFields |
Solo puede hacer referencia a campos que permiten realizar búsquedas. |
Suggest y Autocomplete | searchFields |
Solo puede hacer referencia a campos que forman parte de un proveedor de sugerencias. |
Search, Suggest y Autocomplete | $filter |
Solo puede hacer referencia a campos filtrables. |
Search y Suggest | $orderby |
Solo puede hacer referencia a campos ordenables. |
Search, Suggest y Lookup | $select |
Solo puede hacer referencia a campos recuperables |
Constantes
Las constantes en OData son valores literales de un determinado tipo de Entity Data Model (EDM). Consulte Tipos de datos admitidos para ver una lista de los tipos que se admiten en Azure AI Search. No se admiten constantes de tipos de colección.
En la tabla siguiente se muestran ejemplos de constantes para cada uno de los tipos de datos novector que admiten expresiones de OData:
Tipo de datos | Constantes de ejemplo |
---|---|
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' |
Caracteres especiales de escape en constantes de cadena
Las constantes de cadena en OData están delimitadas por comillas simples. Si tiene que crear una consulta con una constante de cadena que, a su vez, pueda contener comillas simples, puede escapar las comillas incrustadas si las duplica.
Por ejemplo, una frase con un apóstrofo sin formato, como "Alice's car", se representaría en OData como la constante de cadena 'Alice''s car'
.
Importante
Al construir filtros mediante programación, es importante recordar escapar las constantes de cadena que proceden de los datos proporcionados por el usuario. Esto es para mitigar la posibilidad de ataques por inyección de código, en especial cuando se usan filtros para implementar el recorte de seguridad.
Sintaxis de las constantes
El siguiente EBNF (notación de Backus-Naur extendida) define la gramática de la mayoría de las constantes que se muestran en la tabla anterior. La gramática de los tipos geoespaciales se puede encontrar en Funciones geoespaciales de OData en 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'
También está disponible un diagrama de sintaxis interactivo:
Nota:
Consulte Referencia de la sintaxis de expresiones de OData para Azure AI Search para obtener la EBNF completa.
Generación de expresiones a partir de rutas de acceso de campo y constantes
Las rutas de acceso de campo y las constantes son la parte más básica de una expresión de OData, pero ya son expresiones completas por derecho propio. De hecho, el parámetro $select de Azure AI Search no es más que una lista separada por comas de rutas de acceso de campo y $orderby no es mucho más complicado que $select. Si resulta que tiene un campo de tipo Edm.Boolean
en el índice, puede escribir incluso un filtro que no sea si no la ruta de acceso de ese campo. Las constantes true
y false
son igualmente filtros válidos.
Sin embargo, es más común tener expresiones complejas que hacen referencia a más de un campo y constante. Estas expresiones se compilan de diferentes maneras según el parámetro.
La siguiente EBNF (notación de Backus-Naur extendida) define la gramática de los parámetros $filter, $orderby y $select. Estos parámetros se generan a partir de expresiones más sencillas que hacen referencia a las rutas de acceso de campo y a las constantes:
filter_expression ::= boolean_expression
order_by_expression ::= order_by_clause(',' order_by_clause)*
select_expression ::= '*' | field_path(',' field_path)*
También está disponible un diagrama de sintaxis interactivo:
Nota:
Consulte Referencia de la sintaxis de expresiones de OData para Azure AI Search para obtener la EBNF completa.
Pasos siguientes
Los parámetros $orderby y $select son ambos listas separadas por comas de expresiones más sencillas. El parámetro $filter es una expresión booleana que se compone de subexpresiones más sencillas. Estas subexpresiones se combinan mediante operadores lógicos, como and
, or
y not
, operadores de comparación, como eq
, lt
, gt
, etc. y operadores de colección, como any
y all
.
Los parámetros $filter, $orderby, y $select se exploran con más detalle en los siguientes artículos: