你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。

用于关键字搜索的 Azure AI 搜索 筛选器

注释

Azure AI 搜索可通过Azure门户、REST API 和Azure SDK获取。 它也是 Foundry IQ 的基础;Foundry IQ 是一个托管式知识层,可将企业内容转化为供 Microsoft Foundry 门户中的智能体使用的、可复用且具备权限感知能力的知识库。

筛选器提供基于值的条件,用于在查询执行关键字搜索之前包括或排除内容,或者在查询执行矢量搜索之前或之后包括或排除内容。 筛选器应用于非矢量字段,但如果文档包含非矢量字段,则可以在矢量搜索中使用。 例如,对于围绕分块内容组织的索引,你可能具有可筛选的父级字段或元数据字段。

本文介绍如何筛选关键字搜索。 有关向量的详细信息,请参阅 在向量查询中添加筛选器。

使用 OData 筛选器表达式语法指定筛选器。 与关键字和矢量搜索相比,仅当匹配精确时,筛选器才会成功。

何时使用筛选器

筛选器是多个搜索体验的基础,包括“在我附近查找”地理空间搜索、分面导航和安全筛选器,这些筛选器仅显示用户允许查看的文档。 如果实现其中任一体验,则需要筛选器。 它是附加到搜索查询的筛选器,提供地理坐标、用户选择的分面类别或请求者的安全 ID。

常见方案包括:

  • 根据索引中的内容对搜索结果进行切片。 给定具有酒店位置、类别和设施的架构,可以创建一个筛选器来显式匹配条件(在西雅图,靠近水边,有景观)。

  • 实现集成筛选器依赖的搜索体验。

    • 分面导航使用筛选器传回用户选择的分面类别。
    • 地理空间搜索 使用筛选器在“查找我附近”应用中传递当前位置的坐标,并实现基于区域或距离的匹配功能。
    • 安全筛选器 将安全标识符作为筛选器条件传递,其中索引中的匹配项充当文档访问权限的代理。
  • 执行“数字搜索”。 数值字段是可检索的,可以出现在搜索结果中,但它们不能单独搜索(受全文搜索的约束)。 如果需要基于数字数据的选择条件,请使用筛选器。

如何执行筛选器

在查询时,筛选器分析器接受条件作为输入,将表达式转换为表示为树的原子布尔表达式,然后根据索引中的可筛选字段计算筛选器树。

筛选与搜索一起进行,从而限定要包括在下游处理中的文档以供文档检索和相关性评分。 与搜索字符串搭配使用时,筛选器能够有效减小后续搜索操作的重调集。 单独使用时(例如,当查询字符串为空时), search=*筛选器条件是唯一的输入。

如何定义筛选器

筛选器适用于属性为 filterable的字段上的文本和数字(非函数)内容。

筛选器是 OData 表达式,采用由 Azure AI 搜索 支持的 筛选语法。

可以为每个 搜索 操作指定一个筛选器,但筛选器本身可以包含多个字段、多个条件,如果使用函数 ismatch 、多个全文搜索表达式。 在多部分筛选器表达式中,可以按任意顺序指定谓词(受运算符优先规则的约束)。 如果尝试在特定序列中重新排列谓词,则性能没有明显的提升。

筛选器表达式的限制之一是请求的最大大小限制。 对于 POST,整个请求(包括筛选器)最多可以为 16 MB,对于 GET,最多可以为 8 KB。 筛选器表达式中的子句数也有限制。 一个很好的经验法则是,如果你有数百个子句,则有可能达到限制。 我们建议以这样的方式设计您的应用程序,使其不会生成大小无限制的筛选器。

以下示例表示多个 API 中的原型筛选器定义。

POST https://[service name].search.windows.net/indexes/hotels/docs/search?api-version=2026-04-01
{
    "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' in 'dog' or 'siamese' in '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 。 有关字段定义设置的详细信息,请参阅 “创建索引”。

在 Azure SDK 中,可筛选功能默认设置为 off。 可以通过将相应 SearchField 对象的 IsFilterable 属性设置为true可筛选字段。 在下一个示例中,该属性设置在映射到索引定义的模型类的Rating属性上。

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

使现有字段可筛选

无法修改现有字段以使其可筛选。 相反,需要添加新字段或重新生成索引。 有关重新生成索引或重新填充字段的详细信息,请参阅 如何重新生成Azure AI 搜索索引。

文本筛选器基础知识

文本筛选器将字符串字段与筛选器中提供的文本字符串匹配: $filter=Category eq 'Resort and Spa'

与全文搜索不同,文本筛选器没有词法分析或分词,因此比较仅适用于完全匹配项。 例如,假设字段 f 包含“sunny day”, $filter=f eq 'sunny' 不匹配,但 $filter=f eq 'sunny day' 会匹配。

文本字符串区分大小写,这意味着默认情况下文本筛选器区分大小写。 例如,$filter=f eq 'Sunny day' 将无法查找到“sunny day”。 但是,可以使用 规范化器 使过滤不区分大小写。

文本筛选方法

方法 描述 何时使用
search.in 根据字符串分隔列表匹配字段的函数。 建议用于 安全筛选器 和需要与字符串字段匹配许多原始文本值的任何筛选器。 search.in 函数旨在提高速度,相比于显式使用 eq 和 or 将字段与每个字符串进行比较,其速度要快得多。
search.ismatch 一个函数,可用于将全文搜索操作与同一筛选表达式中的布尔筛选操作混合使用。 如果希望在一个请求中使用多个搜索筛选器组合,请使用 search.ismatch (或其评分等效的 search.ismatchscoring)。 还可以将其用于 包含 筛选器,以筛选较大字符串中的部分字符串。
$filter=field operator string 由字段、运算符和值组成的用户定义的表达式。 如果要在字符串字段和字符串值之间查找完全匹配项,请使用此选项。

数字筛选器基础知识

在全文搜索的上下文中,数值字段不适用 searchable。 只有字符串才能进行全文搜索。 例如,如果输入 99.99 作为搜索词,则不会返回价格为 $99.99 的项目。 相反,你会在文档的字符串字段中看到数字为 99 的项目。 因此,如果你有数字数据,假设你会将它们用于过滤器,包括范围、切面、组等。

如果字段被标记 retrievable,则包含数值字段(价格、大小、SKU、ID)的文档在搜索结果中提供这些值。 此处的要点是全文搜索本身不适用于数值字段类型。

后续步骤

首先,在 Azure 门户中尝试 Search explorer,使用 $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 筛选器表达式语法 > 示例。

另请参阅