Обзор языка OData для $filter, $orderbyа также $select в службе "Поиск ИИ Azure"

В этой статье представлен обзор языка выражений OData, используемого в $filter, $order и $select выражений в поиске ИИ Azure. Язык представлен снизу вверх, начиная с самых простых элементов. Выражения OData, которые можно создавать в диапазоне запросов, от простых до сложных, но все они совместно используют общие элементы. Общие элементы включают:

  • Пути к полям, которые ссылаются на определенные поля индекса.
  • Константы, являющиеся прямыми значениями определенного типа данных.

После понимания этих распространенных понятий можно продолжить синтаксис верхнего уровня для каждого выражения:

  • $filter выражения вычисляются во время синтаксического анализа запросов, ограничивают поиск определенным полям или добавляют критерии соответствия, используемые во время сканирования индекса.
  • $orderby выражения применяются как шаг после обработки результирующий набор для сортировки возвращаемых документов.
  • $select выражения определяют, какие поля документов включены в результирующий набор.

Синтаксис этих выражений отличается от простого или полного синтаксиса запросов, используемого в параметре поиска , хотя в синтаксисе для ссылок есть некоторые совпадения.

Примечание.

Терминология в поиске ИИ Azure отличается от стандарта OData несколькими способами. То, что мы называем полем в поиске ИИ Azure, называется свойством в OData и аналогичным образом для пути к полю и пути к свойству. Индекс, содержащий документы в поиске ИИ Azure, обычно называется В OData набором сущностей, содержащими сущности. Терминология поиска ИИ Azure используется в этой ссылке.

Пути к полям

Следующая EBNF (Расширенная форма Бэкуса — Наура) определяет грамматику путей к полям.

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

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

Кроме того, вам может помочь интерактивная схема синтаксиса:

Примечание.

См . справочник по синтаксису выражений OData для поиска ИИ Azure для полного EBNF.

Путь к полю состоит из одного или нескольких идентификаторов, разделенных косыми чертами. Каждый идентификатор представляет собой последовательность символов, которая должна начинаться с буквы ASCII или знака подчеркивания и содержать только буквы ASCII, цифры и символы подчеркивания. Буквы могут быть в верхнем или нижнем регистре.

Идентификатор может ссылаться либо на имя поля, либо на переменную диапазона в контексте выражения коллекции (any или all) фильтра. Переменная диапазона похожа на переменную цикла, которая представляет текущий элемент коллекции. Для сложных коллекций эта переменная представляет объект, поэтому можно использовать пути полей для ссылки на подфилды переменной. Это аналогично точечной нотации во многих языках программирования.

Примеры путей к полям приведены в следующей таблице.

Путь к полю Description
HotelName Ссылается на поле индекса верхнего уровня
Address/City Относится к City подфилду сложного поля в индексе; Address тип Edm.ComplexType в этом примере
Rooms/Type Относится к Type подфилду сложного поля коллекции в индексе; Rooms тип Collection(Edm.ComplexType) в этом примере
Stores/Address/Country Относится к Country подфилду Address подполя сложного поля коллекции в индексе; Stores имеет тип и Address имеет тип Collection(Edm.ComplexType)Edm.ComplexType в этом примере.
room/Type Относится к Type подполю переменной room диапазона, например в выражении фильтра. Rooms/any(room: room/Type eq 'deluxe')
store/Address/Country Относится к Country подфилду Address подполя переменной store диапазона, например в выражении фильтра. Stores/any(store: store/Address/Country eq 'Canada')

Значение пути к полю различается в зависимости от контекста. В фильтрах путь к полю означает значение одного экземпляра поля в текущем документе. В других контекстах, таких как $OrderBy, $selectили в поле поиска в полном синтаксисе Lucene, "путь к полю" означает само поле. Это различие влияет на использование путей к полям в фильтрах.

Пример: путь к полю Address/City. В фильтре это относится к одному городу для текущего документа, например "Сан-Франциско". В отличие от этого, относится к Type подфилду для многих комнат (например, Rooms/Type "стандартный" для первой комнаты, "делюкс" для второй комнаты и т. д.). Так как Rooms/Type не относится к одному экземпляру подполя Type, его нельзя использовать непосредственно в фильтре. Вместо этого для фильтрации по типу комнаты можно использовать лямбда-выражение с переменной диапазона, например:

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

В этом примере переменная диапазона room отображается в пути к полю room/Type. Таким образом, room/Type ссылается на тип текущей комнаты в текущем документе. Это один экземпляр Type подполя, поэтому его можно использовать непосредственно в фильтре.

Использование путей к полям

Пути к полю используются во многих параметрах REST API службы поиска ИИ Azure. В следующей таблице перечислены все места, где их можно использовать, а также все ограничения на их использование.

API Наименование параметра Ограничения
Создание или Обновление индекса suggesters/sourceFields нет
Создание или Обновление индекса scoringProfiles/text/weights Может ссылаться только на поля с возможностью поиска
Создание или Обновление индекса scoringProfiles/functions/fieldName Может ссылаться только на фильтруемые поля
Найти search когда queryType имеет значение full Может ссылаться только на поля с возможностью поиска
Найти facet Может ссылаться только на поля с аспектами
Найти highlight Может ссылаться только на поля с возможностью поиска
Найти searchFields Может ссылаться только на поля с возможностью поиска
Предложение и Автозаполнение searchFields Может ссылаться только на поля, являющиеся частью средства подбора
Поиск, Предложение и Автозаполнение $filter Может ссылаться только на фильтруемые поля
Поиск и Предложение $orderby Может ссылаться только на поля, доступные для сортировки
Поиск, Предложениеи Просмотр $select Может ссылаться только на извлекаемые поля

Константы

Константы в OData — это прямые значения заданного типа Модели данных сущности (EDM). Сведения о поддерживаемых типах данных см. в списке поддерживаемых типов в службе "Поиск ИИ Azure". Константы типов коллекций не поддерживаются.

В следующей таблице показаны примеры констант для каждого из типов данных, поддерживаемых поиском ИИ Azure:

Тип данных Примеры констант
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'

Исключение специальных символов в строковых константах

Строковые константы в OData разделяются одинарными кавычками. Если необходимо создать запрос со строковой константой, которая может содержать одинарные кавычки, можно попытаться исключить внедренные кавычки, выполнив их удвоение.

Например, фраза без форматированного апострофа, такая как "Alice's car" ("автомобиль Алисы"), будет представлена в OData в качестве строковой константы 'Alice''s car'.

Важно!

При создании фильтров программным способом важно помнить о необходимости исключать строковые константы, которые поступают из вводимых пользователем данных. Это позволяет снизить вероятность атак путем внедрения, особенно при использовании фильтров для реализации фильтрации по ролям безопасности.

Синтаксис констант

Следующая EBNF (Расширенная форма Бэкуса — Наура) определяет грамматику для большинства констант, показанных в приведенной выше таблице. Грамматику для геопространствовых типов можно найти в геопространствовых функциях OData в поиске ИИ Azure.

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'

Кроме того, вам может помочь интерактивная схема синтаксиса:

Примечание.

См . справочник по синтаксису выражений OData для поиска ИИ Azure для полного EBNF.

Создание выражений из путей к полям и констант

Пути к полям и константы — это основная часть любого выражения OData, но они сами по себе уже являются полными выражениями. На самом деле , параметр $select в поиске ИИ Azure не является ничего, кроме разделенного запятыми списка путей полей, и $orderby не намного сложнее, чем $select. Если у вас есть поле типа Edm.Boolean в индексе, можно даже написать фильтр, состоящий только из пути к этому полю. Константы true и false также являются допустимыми фильтрами.

Однако в большинстве случаев требуются более сложные выражения, ссылающиеся на более чем одно поле и одну константу. Эти выражения создаются различными способами в зависимости от параметра.

Следующая EBNF (Расширенная форма Бэкуса — Наура) определяет грамматику для параметров $Filter, $orderby и $select. Они основаны на более простых выражениях, которые ссылаются на пути к полям и константы:

filter_expression ::= boolean_expression

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

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

Кроме того, вам может помочь интерактивная схема синтаксиса:

Примечание.

См . справочник по синтаксису выражений OData для поиска ИИ Azure для полного EBNF.

Следующие шаги

Параметры $orderby и $select являются разделенными запятыми списками более простых выражений. Параметр $filter — это логическое выражение, состоящее из более простых вложенных выражений. Эти вложенные выражения объединяются с помощью логических операторов, таких как , orи not, операторы сравнения, такие как and, gtltи т. д., а также операторы сбора, такие как eqany и .all

Параметры $filter, $orderbyи $select подробно рассматриваются в следующих статьях: