Azure 认知搜索中的 OData 比较运算符 - eqnegtltgeleOData comparison operators in Azure Cognitive Search - eq, ne, gt, lt, ge, and le

在 Azure 认知搜索的 OData 筛选表达式中的最基本运算是将某个字段与给定的值进行比较。The most basic operation in an OData filter expression in Azure Cognitive Search is to compare a field to a given value. 可进行两种类型的比较 -- 相等性比较和范围比较。Two types of comparison are possible -- equality comparison, and range comparison. 可以使用以下运算符将字段与常量值进行比较:You can use the following operators to compare a field to a constant value:

相等性运算符:Equality operators:

  • eq:测试某个字段是否等于某个常量值eq: Test whether a field is equal to a constant value
  • ne:测试某个字段是否不等于某个常量值ne: Test whether a field is not equal to a constant value

范围运算符:Range operators:

  • gt:测试某个字段是否大于某个常量值gt: Test whether a field is greater than a constant value
  • lt:测试某个字段是否小于某个常量值lt: Test whether a field is less than a constant value
  • ge:测试某个字段是否大于或等于某个常量值ge: Test whether a field is greater than or equal to a constant value
  • le:测试某个字段是否小于或等于某个常量值le: Test whether a field is less than or equal to a constant value

可以结合使用范围运算符和逻辑运算符来测试某个字段是否在特定的值范围内。You can use the range operators in combination with the logical operators to test whether a field is within a certain range of values. 请参阅本文稍后提供的示例See the examples later in this article.

备注

如果需要,可将常量值放在运算符的左侧,将字段名称放在右侧。If you prefer, you can put the constant value on the left side of the operator and the field name on the right side. 对于范围运算符,比较的含义是相反的。For range operators, the meaning of the comparison is reversed. 例如,如果常量值位于左侧,则 gt 会测试常量值是否大于字段。For example, if the constant value is on the left, gt would test whether the constant value is greater than the field. 还可以使用比较运算符将函数(例如 geo.distance)的结果与值进行比较。You can also use the comparison operators to compare the result of a function, such as geo.distance, with a value. 对于类似于 search.ismatch 的布尔函数,将结果与 truefalse 进行比较是可选的操作。For Boolean functions such as search.ismatch, comparing the result to true or false is optional.

语法Syntax

以下 EBNF(扩展巴科斯-瑙尔范式)定义一个使用比较运算符的 OData 表达式的语法。The following EBNF (Extended Backus-Naur Form) defines the grammar of an OData expression that uses the comparison operators.

comparison_expression ::=
    variable_or_function comparison_operator constant |
    constant comparison_operator variable_or_function

variable_or_function ::= variable | function_call

comparison_operator ::= 'gt' | 'lt' | 'ge' | 'le' | 'eq' | 'ne'

下面还提供了交互式语法图:An interactive syntax diagram is also available:

比较表达式有两种形式。There are two forms of comparison expressions. 它们之间的唯一差别在于,常量是显示在运算符的左侧还是右侧。The only difference between them is whether the constant appears on the left- or right-hand-side of the operator. 运算符另一侧的表达式必须是变量或函数调用。The expression on the other side of the operator must be a variable or a function call. 变量可以是字段名称,或者 Lambda 表达式中的范围变量。A variable can be either a field name, or a range variable in the case of a lambda expression.

可比较的数据类型Data types for comparisons

比较运算符两侧的数据类型必须兼容。The data types on both sides of a comparison operator must be compatible. 例如,如果左侧是 Edm.DateTimeOffset 类型的字段,则右侧必须是日期时间常量。For example, if the left side is a field of type Edm.DateTimeOffset, then the right side must be a date-time constant. 数字数据类型更灵活。Numeric data types are more flexible. 可将任何数字类型的变量和函数与任何其他数字类型的常量进行比较,但存在下表中所述的几项限制。You can compare variables and functions of any numeric type with constants of any other numeric type, with a few limitations, as described in the following table.

变量或函数类型Variable or function type 常量值类型Constant value type 限制Limitations
Edm.Double Edm.Double 比较需要遵循 NaN 特殊规则Comparison is subject to special rules for NaN
Edm.Double Edm.Int64 常量将转换为 Edm.Double,因此大数量级的值会损失精度Constant is converted to Edm.Double, resulting in a loss of precision for values of large magnitude
Edm.Double Edm.Int32 不适用n/a
Edm.Int64 Edm.Double 不允许对 NaN-INFINF 进行比较Comparisons to NaN, -INF, or INF are not allowed
Edm.Int64 Edm.Int64 不适用n/a
Edm.Int64 Edm.Int32 在比较之前,常量将转换为 Edm.Int64Constant is converted to Edm.Int64 before comparison
Edm.Int32 Edm.Double 不允许对 NaN-INFINF 进行比较Comparisons to NaN, -INF, or INF are not allowed
Edm.Int32 Edm.Int64 不适用n/a
Edm.Int32 Edm.Int32 不适用n/a

对于不允许的比较(例如,将 Edm.Int64 类型的字段与 NaN 进行比较),Azure 认知搜索 REST API 将返回“HTTP 400:错误的请求”错误。For comparisons that are not allowed, such as comparing a field of type Edm.Int64 to NaN, the Azure Cognitive Search REST API will return an "HTTP 400: Bad Request" error.

重要

尽管数字类型比较非常灵活,但我们强烈建议在筛选器中编写比较表达式,使常量值的数据类型与要比较的变量或函数的数据类型相同。Even though numeric type comparisons are flexible, we highly recommend writing comparisons in filters so that the constant value is of the same data type as the variable or function to which it is being compared. 混合使用浮点值和整数值时(在这种情况下,隐式转换可能会损失精度),这一点尤其重要。This is especially important when mixing floating-point and integer values, where implicit conversions that lose precision are possible.

nullNaN 的特殊情况Special cases for null and NaN

使用比较运算符时,请务必记住,Azure 认知搜索中的所有非集合字段都有可能为 nullWhen using comparison operators, it's important to remember that all non-collection fields in Azure Cognitive Search can potentially be null. 下表显示了任何一侧可为 null 的比较表达式的所有可能结果:The following table shows all the possible outcomes for a comparison expression where either side can be null:

运算符Operator 只有字段或变量为 null 时的结果Result when only the field or variable is null 只有常量为 null 时的结果Result when only the constant is null 字段或变量和常量都为 null 时的结果Result when both the field or variable and the constant are null
gt false “HTTP 400:错误的请求”错误HTTP 400: Bad Request error “HTTP 400:错误的请求”错误HTTP 400: Bad Request error
lt false “HTTP 400:错误的请求”错误HTTP 400: Bad Request error “HTTP 400:错误的请求”错误HTTP 400: Bad Request error
ge false “HTTP 400:错误的请求”错误HTTP 400: Bad Request error “HTTP 400:错误的请求”错误HTTP 400: Bad Request error
le false “HTTP 400:错误的请求”错误HTTP 400: Bad Request error “HTTP 400:错误的请求”错误HTTP 400: Bad Request error
eq false false true
ne true true false

总而言之,null 仅等于自身,而不小于或大于任何其他值。In summary, null is equal only to itself, and is not less or greater than any other value.

如果索引包含 Edm.Double 类型的字段,而你将 NaN 值上传到这些字段,则在编写筛选器时需要考虑到这种情况。If your index has fields of type Edm.Double and you upload NaN values to those fields, you will need to account for that when writing filters. Azure 认知搜索实现 IEEE 754 标准来处理 NaN 值,使用此类值的比较将生成不明确的结果,如下表所示。Azure Cognitive Search implements the IEEE 754 standard for handling NaN values, and comparisons with such values produce non-obvious results, as shown in the following table.

运算符Operator 至少有一个操作数为 NaN 时的结果Result when at least one operand is NaN
gt false
lt false
ge false
le false
eq false
ne true

总而言之,NaN 不等于任何值(包括自身)。In summary, NaN is not equal to any value, including itself.

比较地理空间数据Comparing geo-spatial data

不能直接将 Edm.GeographyPoint 类型的字段与常量值进行比较,但可以使用 geo.distance 函数。You can't directly compare a field of type Edm.GeographyPoint with a constant value, but you can use the geo.distance function. 此函数返回 Edm.Double 类型的值,因此,可将此值与数字常量进行比较,以根据与固定地理空间坐标之间的距离进行筛选。This function returns a value of type Edm.Double, so you can compare it with a numeric constant to filter based on the distance from constant geo-spatial coordinates. 请参阅下面的示例See the examples below.

比较字符串数据Comparing string data

可以使用 eqne 运算符在筛选器中比较字符串,以找出完全匹配项。Strings can be compared in filters for exact matches using the eq and ne operators. 这些比较区分大小写。These comparisons are case-sensitive.

示例Examples

匹配 Rating 字段为 3 到 5(含)的文档:Match documents where the Rating field is between 3 and 5, inclusive:

Rating ge 3 and Rating le 5

匹配 Location 字段与给定纬度和经度之间的距离小于 2 公里的文档:Match documents where the Location field is less than 2 kilometers from the given latitude and longitude:

geo.distance(Location, geography'POINT(-122.031577 47.578581)') lt 2.0

匹配 LastRenovationDate 字段大于或等于 2015 年 1 月 1 日午夜 (UTC) 的文档:Match documents where the LastRenovationDate field is greater than or equal to January 1st, 2015, midnight UTC:

LastRenovationDate ge 2015-01-01T00:00:00.000Z

匹配 Details/Sku 字段不为 null 的文档:Match documents where the Details/Sku field is not null:

Details/Sku ne null

匹配至少提供一间“豪华客房”,且 Rooms/Type 字段的字符串与筛选器完全匹配的酒店的文档:Match documents for hotels where at least one room has type "Deluxe Room", where the string of the Rooms/Type field matches the filter exactly:

Rooms/any(room: room/Type eq 'Deluxe Room')

后续步骤Next steps