Синтаксис OData $filter в поиске ИИ Azure

Примечание.

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

В поиске ИИ Azure параметр $filter указывает критерии включения или исключения для возврата совпадений в результатах поиска. В этой статье описывается синтаксис OData $filter и приведены примеры.

Описание построения пути полей и констант представлено в обзоре языка OData для поисковых возможностей ИИ Azure. Для получения дополнительной информации о сценариях фильтрации см. раздел Фильтры в Поиск с использованием ИИ Azure.

Синтаксис

Фильтр в языке OData является логическим выражением, которое, в свою очередь, может относиться к одному из нескольких типов, как показано в следующей EBNF (расширенной форме Бэкуса-Наура):

boolean_expression ::=
    collection_filter_expression
    | logical_expression
    | comparison_expression
    | boolean_literal
    | boolean_function_call
    | '(' boolean_expression ')'
    | variable

/* This can be a range variable in the case of a lambda, or a field path. */
variable ::= identifier | field_path

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

Ниже перечислены типы логических выражений.

  • Выражения фильтров коллекции с использованием any и all. Они применяют условия фильтрации к полям коллекции. Дополнительные сведения см. в разделе Операторы сбора OData в службе Поиск с использованием ИИ Azure.
  • Логические выражения, объединяющие другие логические выражения с помощью операторов and, or и not. Дополнительные сведения см. в разделе "Логические операторы OData" в службе "Поиск ИИ Azure".
  • Выражения сравнения, которые сравнивают поля или переменные диапазона с постоянными значениями с помощью операторов eq, ne, gt, lt, ge и le. Для получения дополнительной информации см. операторы сравнения OData в Поиск с использованием ИИ Azure. Выражения сравнения также используются для сравнения расстояний между геопространственными координатами с помощью функции geo.distance. Дополнительные сведения см. в статье о геопространствовых функциях OData в поиске ИИ Azure.
  • Логические литералы true и false. Эти константы могут пригодиться при программном создании фильтров; в иных случаях они не используются на практике.
  • Вызовы булевых функций, включая:
  • Пути полей или диапазонные переменные типа Edm.Boolean. Например, если в индексе есть логическое поле с именем IsEnabled и нужно вернуть все документы, в которых это поле имеет значение true, в качестве критерия фильтрации может быть достаточно указать имя IsEnabled.
  • Логические выражения в скобках. Круглые скобки позволяют явно задать порядок выполнения операций в фильтре. Дополнительные сведения о приоритете операторов OData по умолчанию см. в следующем разделе.

Приоритет операторов в фильтрах

Если вы пишете выражение фильтра без круглых скобок вокруг его подвыражений, служба поиска Azure AI будет обрабатывать его в соответствии с набором правил приоритета операторов. Эти правила основаны на том, какие операторы используются для объединения вложенных выражений. В таблице ниже перечислены группы операторов в порядке убывания приоритета.

Группа Операторы
Логические операторы not
Операторы сравнения eq ne, gt, lt, ge, le
Логические операторы and
Логические операторы or

Оператор, указанный выше в таблице, "теснее" привязан к своим операндам по сравнению с другими операторами. Например, and имеет более высокий приоритет, чем or, а приоритет операторов сравнения еще выше, поэтому следующие два выражения эквивалентны:

    Rating gt 0 and Rating lt 3 or Rating gt 7 and Rating lt 10
    ((Rating gt 0) and (Rating lt 3)) or ((Rating gt 7) and (Rating lt 10))

Оператор not имеет наивысший приоритет среди всех остальных (даже выше, чем операторы сравнения). Поэтому, если вы попробуете написать фильтр вот так:

    not Rating gt 5

Вы получите следующее сообщение об ошибке:

    Invalid expression: A unary operator with an incompatible type was detected. Found operand type 'Edm.Int32' for operator kind 'Not'.

Эта ошибка возникает потому, что оператор связан только с полем Rating типа Edm.Int32, а не со всем выражением сравнения. Чтобы устранить эту проблему, поместите операнд not в круглые скобки:

    not (Rating gt 5)

Ограничения на размер фильтров

Существуют ограничения на размер и сложность выражений фильтров, которые можно отправлять в поиск ИИ Azure. Ограничения ориентировочно основаны на количестве предложений в выражении фильтрации. Общее правило следующее: при наличии нескольких сотен предложений есть риск превысить лимит. Рекомендуем разрабатывать приложения таким образом, чтобы оно не создавало фильтры неограниченного размера.

Совет

Чтобы избежать ограничения на количество условий в фильтре, вместо использования множества операций сравнения на равенство можно воспользоваться функцией search.in, так как вызов функции считается одним условием.

Примеры

Найти все отели, в которых хотя бы один номер имеет базовый тариф меньше 200 долларов и с рейтингом не ниже 4:

    $filter=Rooms/any(room: room/BaseRate lt 200.0) and Rating ge 4

Найдите все отели, кроме "Sea View Motel", которые были отремонтированы с 2010 года.

    $filter=HotelName ne 'Sea View Motel' and LastRenovationDate ge 2010-01-01T00:00:00Z

Найти все отели с ремонтом 2010 года и более поздним. Литерал DateTime указан в часовом поясе тихоокеанского стандартного времени:

    $filter=LastRenovationDate ge 2010-01-01T00:00:00-08:00

Найти все отели, в которых есть парковка и во всех номерах запрещено курить:

    $filter=ParkingIncluded and Rooms/all(room: not room/SmokingAllowed)

- ИЛИ -

    $filter=ParkingIncluded eq true and Rooms/all(room: room/SmokingAllowed eq false)

Найти все отели класса люкс или отели с рейтингом 5, в которых есть парковка:

    $filter=(Category eq 'Luxury' or ParkingIncluded eq true) and Rating eq 5

Найти все отели с тегом "wifi" как минимум в одном номере (где у каждого номера теги хранятся в поле Collection(Edm.String)):

    $filter=Rooms/any(room: room/Tags/any(tag: tag eq 'wifi'))

Найти все отели с любыми номерами:

    $filter=Rooms/any()

Найти все отели без номеров:

    $filter=not Rooms/any()

Найти все отели в пределах 10 километров от заданного ориентира (где Location — это поле типа Edm.GeographyPoint):

    $filter=geo.distance(Location, geography'POINT(-122.131577 47.678581)') le 10

Найти все отели в заданном окне просмотра, описанном как многоугольник (где Location — это поле типа Edm.GeographyPoint). Многоугольник должен быть замкнут, то есть первая и конечная точки должны совпадать. Кроме того, точки многоугольника должны быть указаны в порядке против часовой стрелки.

    $filter=geo.intersects(Location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')

Найти все отели, в которых поле описания имеет значение null. Поле имеет значение null, если оно не было задано или было явно задано как null:

    $filter=Description eq null

Найти все отели с именем Sea View motel или Budget hotel. Эти фразы содержат пробелы, а пробел — разделитель по умолчанию. Вы можете указать альтернативный разделитель в одинарных кавычках в качестве третьего строкового параметра:

    $filter=search.in(HotelName, 'Sea View motel,Budget hotel', ',')

Найти все отели с названием Sea View motel или Budget hotel; названия разделены знаком "|":

    $filter=search.in(HotelName, 'Sea View motel|Budget hotel', '|')

Найти все отели, где все номера имеют тег wifi или pool:

    $filter=Rooms/any(room: room/Tags/any(tag: search.in(tag, 'wifi, tub')))

Найти совпадение по фразам в коллекции, например, «подогреваемые стойки для полотенец» или «фен в комплекте» в тегах.

    $filter=Rooms/any(room: room/Tags/any(tag: search.in(tag, 'heated towel racks,hairdryer included', ','))

Найти документы со словом "набережная". Этот запрос фильтрации идентичен поисковому запросу с search=waterfront:

    $filter=search.ismatchscoring('waterfront')

Найти документы со словом hostel и рейтингом, большим или равным 4, или документы со словом motel и рейтингом 5. Этот запрос невозможно выразить без функции search.ismatchscoring, так как в нем полнотекстовый поиск сочетается с операциями фильтрации с помощью or.

    $filter=search.ismatchscoring('hostel') and rating ge 4 or search.ismatchscoring('motel') and rating eq 5

Найти документы без слова «роскошь».

    $filter=not search.ismatch('luxury')

Найти документы с фразой «вид на океан» или рейтингом 5. Запрос search.ismatchscoring будет выполняться только по отношению к полям HotelName и Description. Также будут возвращены документы, которые соответствуют только второму условию дизъюнкции: отели со значением 5 в поле Rating. Эти документы будут возвращены с нулевым баллом, чтобы было ясно, что они не соответствуют ни одному из оцениваемых элементов выражения.

    $filter=search.ismatchscoring('"ocean view"', 'Description,HotelName') or Rating eq 5

Найти отели, в которых слова hotel (гостиница) и airport (аэропорт) разделены не более чем пятью словами, а все номера являются некурящими. В этом запросе используется полный язык запросов Lucene.

    $filter=search.ismatch('"hotel airport"~5', 'Description', 'full', 'any') and not Rooms/any(room: room/SmokingAllowed)

Найти документы, которые содержат в поле "Описание" слово, начинающееся с букв "lux". В этом запросе используется префиксный поиск в сочетании с search.ismatch.

    $filter=search.ismatch('lux*', 'Description')

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