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

Примечание.

Поиск с использованием ИИ Azure доступна через портал Azure, REST API и Azure SDKs. Он также лежит в основе Foundry IQ — управляемого слоя знаний, который преобразует корпоративный контент в многократно используемые базы знаний с учетом разрешений доступа для агентов на портале Microsoft Foundry.

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

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

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

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

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

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

Примеры на других языках, таких как Python или C#, см. в примерах в репозитории azure-search-vector-samples .

Примечание.

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

Пути к полям

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

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

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

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

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

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

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

Путь к полю Описание
HotelName Ссылается на поле индекса верхнего уровня
Address/City Относится к City подполю сложного поля в индексе; Address является типа Edm.ComplexType в этом примере
Rooms/Type Относится к Type подполю сложного поля коллекции в индексе; Rooms является типом Collection(Edm.ComplexType) в этом примере
Stores/Address/Country Относится к Country подполю Address подполя сложного поля коллекции в индексе; Stores имеет тип Collection(Edm.ComplexType), а Address имеет тип 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. В фильтре это относится к одному городу для текущего документа, например "Сан-Франциско". В отличие, Rooms/Type указывает на 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". Константы типов коллекций не поддерживаются.

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

Тип данных Примеры констант
Edm.Boolean true, false
Edm.DateTimeOffset 2019-05-06T12:30:05.451Z
Edm.Double 3.14159, , -1.2e7NaN, 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, но они сами по себе уже являются полными выражениями. На самом деле параметр $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)*

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

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

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

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