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

В поиске ИИ 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

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

Примечание.

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

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

  • Выражения фильтров коллекции с использованием 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, , neltgtge,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')))

Найти совпадение по фразам в коллекции, например heated towel racks (подогреваемые стойки для полотенец) или hairdryer included (фен в комплекте) в тегах.

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

Найти документы со словом waterfront. Этот запрос фильтрации идентичен поисковому запросу с 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

Найти документы без слова luxury.

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

Найти документы с фразой "ocean view" или рейтингом 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')

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