Фильтры в текстовых запросах

Фильтр предоставляет критерии на основе значений для включения или исключения содержимого перед выполнением запроса. Например, включая или исключая документы на основе дат, расположений или языков. Фильтры задаются в отдельных полях. Определение поля должно быть присвоено как "фильтруемое", если вы хотите использовать его в выражениях фильтров.

Фильтр указывается с помощью синтаксиса выражения фильтра OData. В отличие от полнотекстового поиска фильтр завершается успешно, только если совпадение точно.

Когда следует использовать фильтр

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

Распространенные сценарии включают в себя:

  • Срез результатов поиска на основе содержимого в индексе. Учитывая схему с расположением, категориями и удобствами отеля, вы можете создать фильтр для явного сопоставления по критерию (в Сиэтле, на воде, с видом).

  • Реализация интерфейса поиска поставляется с зависимостью фильтра:

    • Навигация по аспектам использует фильтр для возврата категории аспекта, выбранной пользователем.
    • Геопространственный поиск использует фильтр для передачи координат текущего расположения в приложениях и функциях, которые соответствуют области или по расстоянию.
    • Фильтры безопасности передают идентификаторы безопасности в качестве критериев фильтрации, где совпадение в индексе служит прокси-сервером для получения прав доступа к документу.
  • Выполните поиск по фразе "поиск чисел". Числовые поля являются извлекаемыми и могут отображаться в результатах поиска, но они не доступны для поиска (при условии полнотекстового поиска) по отдельности. Если вам нужны критерии выбора, основанные на числовых данных, используйте фильтр.

Как выполняются фильтры

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

Фильтрация происходит совместно с поиском. При этом определяется, какие документы включать в последующую обработку для поиска документов и оценки релевантности. При совместном использовании со строкой поиска фильтр эффективно уменьшает набор повторных вызовов последующей операции поиска. При использовании отдельно (например, когда строка запроса пуста, где search=*), критерием фильтра являются только входные данные.

Определение фильтров

Фильтры — это выражения OData, сформулированные в синтаксисе фильтра, поддерживаемом поиском ИИ Azure.

Можно указать один фильтр для каждой операции поиска , но сам фильтр может включать несколько полей, несколько критериев и, если вы используете функцию, несколько выражений полнотекстового ismatch поиска. В выражении фильтра, состоящего из нескольких частей, предикаты можно указывать в любом порядке (с учетом правил приоритета операторов). При попытке переупорядочения предикатов в определенной последовательности нет заметного повышения производительности.

Одним из ограничений, применяемых к выражениям фильтра, является ограничение на максимальный размер запроса. Весь запрос, включая функции фильтра, не может содержать более 16 МБ данных для POST или 8 КБ для GET. Существует также ограничение на количество предложений в выражении фильтра. Хорошее проверенное правило: если у вас есть сотни предложений, вы рискуете превысить лимит. Рекомендуем разрабатывать приложения таким образом, чтобы оно не создавало фильтры неограниченного размера.

Следующие примеры представляют собой прототипные определения фильтров в нескольких API.

POST https://[service name].search.windows.net/indexes/hotels/docs/search?api-version=2020-06-30
{
    "search": "*",
    "filter": "Rooms/any(room: room/BaseRate lt 150.0)",
    "select": "HotelId, HotelName, Rooms/Description, Rooms/BaseRate"
}
options = new SearchOptions()
{
    Filter = "Rating gt 4",
    OrderBy = { "Rating desc" }
};

Шаблоны фильтров

В следующих примерах показаны несколько шаблонов использования для сценариев фильтра. Дополнительные идеи см. в примерах синтаксиса > выражений OData.

  • Автономный параметр $filter без строки запроса полезен, когда выражение фильтра может полностью определить интересующие документы. Без строки запроса нет лексического или лингвистического анализа, ни оценки, ни ранжирования. Обратите внимание, что строка поиска являет собой звездочку, что означает "сопоставить все документы".

    {
      "search": "*",
      "filter": "Rooms/any(room: room/BaseRate ge 60 and room/BaseRate lt 300) and Address/City eq 'Honolulu"
    }
    
  • Сочетание строки запроса и $filter, где фильтр создает подмножество, а строка запроса предоставляет термины для полнотекстового поиска по отфильтрованному подмножеству. Добавление терминов ("театры в пешей доступности") вводит в результаты поиска баллы. При этом документы с наилучшим совпадением будут расположены выше. Использование фильтра со строкой запроса является наиболее распространенным шаблоном использования.

    {
      "search": "walking distance theaters",
      "filter": "Rooms/any(room: room/BaseRate ge 60 and room/BaseRate lt 300) and Address/City eq 'Seattle'"
    }
    
    
  • Составные запросы, разделенные с помощью логического оператора or, каждый со своими критериями фильтра (например, beagles в категории dog или siamese в категории cat). Выражения в сочетании с or вычисляются по отдельности с объединением документов, соответствующих каждому выражению, отправляемому обратно в ответе. Этот шаблон использования достигается с помощью search.ismatchscoring функции. Кроме того, можно использовать версию, search.ismatchне относяющуюся к атрибуту.

    # Match on hostels rated higher than 4 OR 5-star motels.
    $filter=search.ismatchscoring('hostel') and Rating ge 4 or search.ismatchscoring('motel') and Rating eq 5
    
    # Match on 'luxury' or 'high-end' in the description field OR on category exactly equal to 'Luxury'.
    $filter=search.ismatchscoring('luxury | high-end', 'Description') or Category eq 'Luxury'&$count=true
    

    Кроме того, можно объединить полнотекстовый поиск с search.ismatchscoring фильтрами, используя and вместо orэтого, но это функционально эквивалентно использованию search и $filter параметрам в запросе поиска. Например, следующие два запроса приводят к одному результату:

    $filter=search.ismatchscoring('pool') and Rating ge 4
    
    search=pool&$filter=Rating ge 4
    

Требования к полям для фильтрации

В REST API фильтрация включена по умолчанию для простых полей. Фильтруемые поля увеличивают размер индекса. Не забудьте установить "filterable": false для полей, которые вы не планируете фактически использовать в фильтре. Дополнительные сведения о параметрах для определения полей см. в статье Create Index (Azure Search Service REST API) (Создание индекса (REST API службы "Поиск Azure")).

В пакете SDK для .NET фильтруемые поля отключены по умолчанию. Вы можете выполнить фильтрацию полей, задав для свойства IsFilterable соответствующего объекта SearchField значение true. В следующем примере атрибут задается в Rating свойстве класса модели, который сопоставляется с определением индекса.

[SearchField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
public double? Rating { get; set; }

Как изменить существующее поле таким образом, чтобы оно стало фильтруемым

Существующие поля нельзя сделать фильтруемыми. Вместо этого нужно добавить новое поле или перестроить индекс. Дополнительные сведения о перестроении индекса или повторения полей см. в статье "Как перестроить индекс поиска ИИ Azure".

Принципы работы текстовых фильтров

Текстовые фильтры соответствуют строковым полям строк литералов, которые вы задаете в фильтре: $filter=Category eq 'Resort and Spa'

В отличие от полнотекстового поиска, нет лексического анализа или разбиения слов для текстовых фильтров, поэтому сравнения предназначены только для точных совпадений. Например, предположим, что поле f содержит "солнечный день", $filter=f eq 'sunny' не соответствует, но $filter=f eq 'sunny day' будет.

Текстовые строки чувствительны к регистру, что означает, что текстовые фильтры чувствительны к регистру по умолчанию. Например, $filter=f eq 'Sunny day' не будет находить "солнечный день". Однако вы можете использовать нормализатор , чтобы сделать его так, чтобы фильтрация не учитывает регистр.

Подходы к фильтрации по тексту

Подход Description Варианты использования
search.in Функция, которая сопоставляет поле со списком строк с разделителями. Является рекомендуемым для фильтров безопасности и любых фильтров, где многие значения необработанного текста необходимо сопоставлять со строковым полем. Функция search.in разработана для ускорения и выполняется намного быстрее, чем явное сравнение поля с каждой строкой с помощью eq и or.
search.ismatch Функция, которая позволяет совместно использовать операции полнотекстового поиска вместе с операциями строго логического фильтра в одном выражении фильтра. Используйте search.ismatch (или его эквивалент, search.ismatchscoring), если в одном запросе требуется несколько сочетаний фильтров поиска. Вы также можете использовать ее для фильтра contains (для фильтрации в частичной строке в контексте большей строки).
$filter=field operator string Определенное пользователем выражение, состоящее из поля, операторов и значений. Используйте этот параметр, если нужно найти точные соответствия между строковым полем и строковым значением.

Основные компоненты числового фильтра

Числовые поля не searchable являются контекстом полнотекстового поиска. Только строки подлежат полному текстовому поиску. Например, при вводе 99,99 в качестве поискового запроса вы не сможете найти товары по цене 99,99 доллара США. Вместо этого отображаются элементы, которые содержат строку поля документа с номером 99. Таким образом, если у вас есть числовые данные, предполагается, что они будут использоваться для фильтров, включая диапазоны, аспекты, группы и т. д.

Документы, содержащие числовые поля (цена, размер, SKU, идентификатор), предоставляют эти значения в результатах поиска, если поле отмечено retrievable. Ниже приведена точка, что сам полнотекстовый поиск не применим к числовым типам полей.

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

Сначала попробуйте использовать обозреватель поиска на портале, чтобы отправить запросы с параметрами $filter. Пример индекса выборки недвижимости предоставляет полезные результаты для следующих отфильтрованных запросов при их вставке в строку поиска:

# Geo-filter returning documents within 5 kilometers of Redmond, Washington state
# Use $count=true to get a number of hits returned by the query
# Use $select to trim results, showing values for named fields only
# Use search=* for an empty query string. The filter is the sole input

search=*&$count=true&$select=description,city,postCode&$filter=geo.distance(location,geography'POINT(-122.121513 47.673988)') le 5

# Numeric filters use comparison like greater than (gt), less than (lt), not equal (ne)
# Include "and" to filter on multiple fields (baths and bed)
# Full text search is on John Leclerc, matching on John or Leclerc

search=John Leclerc&$count=true&$select=source,city,postCode,baths,beds&$filter=baths gt 3 and beds gt 4

# Text filters can also use comparison operators
# Wrap text in single or double quotes and use the correct case
# Full text search is on John Leclerc, matching on John or Leclerc

search=John Leclerc&$count=true&$select=source,city,postCode,baths,beds&$filter=city gt 'Seattle'

Дополнительные примеры см. в разделе "Примеры синтаксиса выражений > фильтра OData".

См. также