Azure AI 搜索中的 OData 集合运算符 - any
和 all
在编写 OData 筛选器表达式以用于 Azure AI 搜索时,对集合字段进行筛选通常很有用。 可以使用 any
和 all
运算符实现这一点。
语法
以下 EBNF(扩展巴科斯-瑙尔范式)定义了使用 any
或 all
的 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
。
- 如果集合的每个元素的谓词都为 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.ismatch 和 search.ismatchscoring 外的所有内容 |
相同 |
Collection(Edm.String) |
使用 eq 或 search.in 进行比较 使用 or 组合子表达式 |
使用 ne 或 not search.in() 进行比较 使用 and 组合子表达式 |
Collection(Edm.Boolean) |
使用 eq 或 ne 进行比较 |
相同 |
Collection(Edm.GeographyPoint) |
将 geo.distance 与 lt 或 le 配合使用 geo.intersects 使用 or 组合子表达式 |
将 geo.distance 与 gt 或 ge 配合使用 not geo.intersects(...) 使用 and 组合子表达式 |
若要更详细地了解这些限制和相关示例,请参阅排查 Azure AI 搜索中的集合筛选器问题。 若要更深入地了解为何存在这些限制,请参阅了解 Azure AI 搜索中的集合筛选器。