Azure AI 搜索中的 OData 集合运算符 - anyall

在编写 OData 筛选器表达式以用于 Azure AI 搜索时,对集合字段进行筛选通常很有用。 可以使用 anyall 运算符实现这一点。

语法

以下 EBNF(扩展巴科斯-瑙尔范式)定义了使用 anyall 的 OData 表达式的语法。

collection_filter_expression ::=
    field_path'/all(' lambda_expression ')'
    | field_path'/any(' lambda_expression ')'
    | field_path'/any()'

lambda_expression ::= identifier ':' boolean_expression

下面还提供了交互式语法图:

注意

请参阅适用于 Azure AI 搜索的 OData 表达式语法参考以获取完整的 EBNF。

有三种形式的表达式可以筛选集合。

  • 前两个表达式遍历集合字段,将以 lambda 表达式形式给定的谓词应用于集合的每个元素。
    • 如果集合的每个元素的谓词都为 true,则使用 all 的表达式将返回 true
    • 如果集合的至少一个元素的谓词为 true,则使用 any 的表达式将返回 true
  • 第三种形式的集合筛选器使用不带 lambda 表达式的 any 来测试集合字段是否为空。 如果集合有任何元素,则返回 true。 如果集合为空,则返回 false

集合筛选器中的 lambda 表达式类似于编程语言中的循环体。 它定义了一个变量,称为范围变量,它在迭代期间保存集合的当前元素。 它还定义了另一个布尔表达式,该表达式是应用于集合的每个元素的范围变量的筛选条件。

示例

匹配 tags 字段恰好包含字符串“wifi”的文档:

tags/any(t: t eq 'wifi')

匹配其中 ratings 字段的每个元素介于 3 和 5 之间(包括 3 和 5)的文档:

ratings/all(r: r ge 3 and r le 5)

匹配其中 locations 字段中任何地理坐标在给定多边形内的文档:

locations/any(loc: geo.intersects(loc, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))

匹配其中 rooms 字段为空的文档:

not rooms/any()

匹配 rooms/amenities 字段包含“tv”且 rooms/baseRate 小于 100(针对所有房间)的文档:

rooms/all(room: room/amenities/any(a: a eq 'tv') and room/baseRate lt 100.0)

限制

并非每个筛选器表达式功能都可在 Lambda 表达式主体中使用。 根据要筛选的集合字段的数据类型,限制会有所不同。 下表总结了这些限制。

数据类型 any 的 lambda 表达式中允许的功能 all 的 lambda 表达式中允许的功能
Collection(Edm.ComplexType) search.ismatchsearch.ismatchscoring 外的所有内容 相同
Collection(Edm.String) 使用 eqsearch.in 进行比较

使用 or 组合子表达式
使用 nenot search.in() 进行比较

使用 and 组合子表达式
Collection(Edm.Boolean) 使用 eqne 进行比较 相同
Collection(Edm.GeographyPoint) geo.distanceltle 配合使用

geo.intersects

使用 or 组合子表达式
geo.distancegtge 配合使用

not geo.intersects(...)

使用 and 组合子表达式

若要更详细地了解这些限制和相关示例,请参阅排查 Azure AI 搜索中的集合筛选器问题。 若要更深入地了解为何存在这些限制,请参阅了解 Azure AI 搜索中的集合筛选器

后续步骤