标量过滤规则
概述
谓词表达式输出一个布尔值。Milvus 通过谓词搜索进行标量过滤。谓词表达式在求值时返回 TRUE 或 FALSE。有关使用谓词表达式的说明,请查看Python SDK API 参考。
EBNF语法规则描述了布尔表达式规则:
Expr = LogicalExpr | NIL
LogicalExpr = LogicalExpr BinaryLogicalOp LogicalExpr
| UnaryLogicalOp LogicalExpr
| "(" LogicalExpr ")"
| SingleExpr;
BinaryLogicalOp = "&&" | "and" | "||" | "or";
UnaryLogicalOp = "not";
SingleExpr = TermExpr | CompareExpr;
TermExpr = IDENTIFIER "in" ConstantArray;
Constant = INTEGER | FLOAT
ConstantExpr = Constant
| ConstantExpr BinaryArithOp ConstantExpr
| UnaryArithOp ConstantExpr;
ConstantArray = "[" ConstantExpr { "," ConstantExpr } "]";
UnaryArithOp = "+" | "-"
BinaryArithOp = "+" | "-" | "*" | "/" | "%" | "**";
CompareExpr = IDENTIFIER CmpOp IDENTIFIER
| IDENTIFIER CmpOp ConstantExpr
| ConstantExpr CmpOp IDENTIFIER
| ConstantExpr CmpOpRestricted IDENTIFIER CmpOpRestricted ConstantExpr;
CmpOpRestricted = "<" | "<=";
CmpOp = ">" | ">=" | "<" | "<=" | "=="| "!=";
MatchOp = "like" | "LIKE";
JsonArrayOps = JsonDefs "(" IDENTIFIER "," JsonExpr | JsonArray ")";
JsonArrayDefs = "json_contains" | "JSON_CONTAINS"
| "json_contains_all" | "JSON_CONTAINS_ALL"
| "json_contains_any" | "JSON_CONTAINS_ANY";
JsonExpr = Constant | ConstantArray | STRING | BOOLEAN;
JsonArray = "[" JsonExpr { "," JsonExpr } "]";
ArrayOps = ArrayDefs "(" IDENTIFIER "," ArrayExpr | Array ")";
ArrayDefs = "array_contains" | "ARRAY_CONTAINS"
| "array_contains_all" | "ARRAY_CONTAINS_ALL"
| "array_contains_any" | "ARRAY_CONTAINS_ANY"
| "array_length" | "ARRAY_LENGTH";
ArrayExpr = Constant | ConstantArray | STRING | BOOLEAN;
Array = "[" ArrayExpr { "," ArrayExpr } "]";
下表列出了上述布尔表达式规则中提到的每个符号的说明。
符号 | 描述 |
---|---|
= | 定义 |
, | 连接。 |
; | 终止。 |
| | 交替。 |
{...} | 重复。 |
(...) | 分组。 |
无 | 空。表达式可以是空字符串。 |
整数 | 整数,如 1、2、3。 |
浮点数 | 浮点数,如 1.0、2.0。 |
CONST | 整数或浮点数。 |
IDENTIFIER | 标识符。在 Milvus 中,IDENTIFIER 表示字段名称。 |
逻辑运算符 | LogicalOp 是一种逻辑操作符,支持在一次比较中结合多个关系操作。逻辑运算符的返回值为 TRUE (1) 或 FALSE (0)。逻辑运算符有两种类型,包括二元逻辑运算符(BinaryLogicalOps)和一元逻辑运算符(UnaryLogicalOps)。 |
单元逻辑操作 | UnaryLogicalOp 指的是一元逻辑运算符 "not"。 |
二进制逻辑运算符 | 对两个操作数执行操作的二元逻辑运算符。在有两个或多个操作数的复杂表达式中,运算顺序取决于优先级规则。 |
算术运算符 | 算术运算符(ArithmeticOp),即算术运算符,对操作数执行加法和减法等数学运算。 |
单值运算符 | 一元算术运算符(UnaryArithOp)是对单一操作数进行运算的算术运算符。负的 UnaryArithOp 可以将正表达式变为负表达式,也可以反过来。 |
二进制算术运算 | BinaryArithOp 即二进制运算符,对两个操作数进行运算。在有两个或多个操作数的复杂表达式中,运算顺序取决于优先级规则。 |
CmpOp | CmpOp 是对两个操作数执行操作的关系运算符。 |
CmpOpRestricted | CmpOpRestricted 仅限于 "小于 "和 "等于"。 |
常量表达式 | ConstantExpr 可以是一个常量,也可以是两个 ConstantExpr 上的二元 ArithOp 或单个 ConstantExpr 上的一元 ArithOp。它是递归定义的。 |
常量数组 | ConstantArray 由方括号封装,ConstantExpr 可以在方括号中重复。ConstArray 必须至少包含一个 ConstantExpr。 |
TermExpr | TermExpr 用于检查 IDENTIFIER 的值是否出现在 ConstantArray 中。TermExpr 用 "in "表示。 |
比较表达式 | CompareExpr 即比较表达式,可以是对两个 IDENTIFIER 的关系操作,也可以是对一个 IDENTIFIER 和一个 ConstantExpr 的关系操作,还可以是对两个 ConstantExpr 和一个 IDENTIFIER 的三元操作。 |
单表达式 | SingleExpr 即单一表达式,可以是 TermExpr 或 CompareExpr。 |
逻辑表达式 | LogicalExpr 可以是两个 LogicalExpr 上的二进制逻辑操作(BinaryLogicalOp),也可以是单个 LogicalExpr 上的一元逻辑操作(UnaryLogicalOp),还可以是括号内分组的 LogicalExpr 或 SingleExpr。LogicalExpr 是递归定义的。 |
Expr | Expr 是表达式的缩写,可以是 LogicalExpr 或 NIL。 |
匹配运算符 | MatchOp 即匹配运算符,用于将字符串与字符串常量或字符串前缀、后缀或后缀常量进行比较。 |
JsonArrayOp | JsonOp 即 JSON 运算符,用于检查指定标识符是否包含指定元素。 |
ArrayOp | ArrayOp 即数组运算符,用于检查指定标识符是否包含指定元素。 |
操作符
逻辑运算符
逻辑运算符在两个表达式之间进行比较。
符号 | 操作 | 示例 | 说明 |
---|---|---|---|
和' && | 和 | expr1 && expr2 | 如果 expr1 和 expr2 均为真,则为真。 |
或 | 或 | expr1 || expr2 | 如果 expr1 或 expr2 均为真,则为真。 |
二进制算术运算符
二进制算术运算符包含两个操作数,可以执行基本算术运算并返回相应的结果。
符号 | 运算 | 示例 | 说明 |
---|---|---|---|
+ | 加法 | a + b | 将两个操作数相加。 |
- | 减法 | a - b | 用第一个操作数减去第二个操作数。 |
* | 乘法 | a * b | 将两个操作数相乘。 |
/ | 除法 | a / b | 用第一个操作数除以第二个操作数。 |
** | 幂 | a ** b | 将第一个操作数提高到第二个操作数的幂。 |
% | 模数 | a % b | 用第一个操作数除以第二个操作数,得到余数部分。 |
关系运算符
关系运算符使用符号检查两个表达式之间的相等、不等或相对顺序。
符号 | 操作 | 示例 | 说明 |
---|---|---|---|
< | 小于 | a < b | 如果 a 小于 b,则为 True。 |
> | 大于 | a > b | 如果 a 大于 b,则为真。 |
== | 相等 | a == b | 如果 a 等于 b,则为 True。 |
!= | 不相等 | a != b | 如果 a 不等于 b,则为真。 |
<= | 小于或等于 | a <= b | 如果 a 小于或等于 b,则为真。 |
>= | 大于或等于 | a >= b | 如果 a 大于或等于 b,则为 True。 |
运算符的优先级和关联性
下表列出了运算符的优先级和关联性。操作符从上到下按优先级递减排列。
优先级 | 运算符 | 说明 | 关联性 |
---|---|---|---|
1 | + - | 一元运算符 | 从左至右 |
2 | 非 | 一元逻辑运算 | 从右到左 |
3 | ** | 二进制逻辑运算 | 从左至右 |
4 | * / % | 二进制 | 从左至右 |
5 | + - | 二进制 | 从左至右 |
6 | < <= > >= | CmpOp | 从左至右 |
7 | == != | CmpOp | 从左至右 |
8 | 像 LIKE | MatchOp | 从左至右 |
9 | json_contains JSON_CONTAINS | JsonArrayOp | 从左至右 |
9 | array_contains ARRAY_CONTAINS | ArrayOp | 从左至右 |
10 | json_contains_all JSON_CONTAINS_ALL | JsonArrayOp | 从左至右 |
10 | array_contains_all ARRAY_CONTAINS_ALL | ArrayOp | 从左至右 |
11 | json_contains_any JSON_CONTAINS_ANY | JsonArrayOp | 从左至右 |
11 | array_contains_any ARRAY_CONTAINS_ANY | ArrayOp | 从左至右 |
12 | array_length ARRAY_LENGTH | 数组操作 | 从左至右 |
13 | && 和 | BinaryLogicOp | 从左至右 |
14 | || 或 | 二进制逻辑操作 | 从左到右 |
表达式通常从左到右求值。复杂表达式一次求值一个。表达式的求值顺序由所用运算符的优先级决定。
如果表达式包含两个或两个以上具有相同优先级的运算符,则先运算左边的运算符。
例如,10 / 2 * 5 将被求值为 (10 / 2),结果乘以 5。
如果先处理优先级较低的运算,则应将其置于括号内。
例如,30 / 2 + 8。通常情况下,它的运算结果是 30 除以 2,然后在结果上加上 8。如果要除以 2 + 8,则应写成 30 / (2+8)。
括号可以嵌套在表达式中。最内层的括号表达式先被求值。
使用方法
Milvus 中所有可用布尔表达式的用法示例如下(int64
表示包含 INT64 类型数据的标量字段,float
表示包含浮点类型数据的标量字段,VARCHAR
表示包含 VARCHAR 类型数据的标量字段):
- CmpOp
"int64 > 0"
"0 < int64 < 400"
"500 <= int64 < 1000"
VARCHAR > "str1"
- BinaryLogicalOp 和括号
"(int64 > 0 && int64 < 400) or (int64 > 500 && int64 < 1000)"
- TermExpr 和 UnaryLogicOp
"int64 not in [1, 2, 3]"
VARCHAR not in ["str1", "str2"]
- TermExpr、BinaryLogicalOp 和 CmpOp(在不同字段上)
"int64 in [1, 2, 3] and float != 2"
- BinaryLogicalOp 和 CmpOp
"int64 == 0 || int64 == 1 || int64 == 2"
- CmpOp 和 UnaryArithOp 或 BinaryArithOp
"200+300 < int64 <= 500+500"
- MatchOp
VARCHAR like "prefix%"
VARCHAR like "%suffix"
VARCHAR like "%middle%"
VARCHAR like "_suffix"
- JsonArrayOp
JSON_CONTAINS(identifier, JsonExpr)
如果
JSON_CONTAINS
(第二个参数)语句的 JSON 表达式是一个 list,则标识符(第一个参数)应是 list 的 list。否则,语句的值总是 False。# {"x": [1,2,3]} json_contains(x, 1) # ==> true json_contains(x, "a") # ==> false # {"x": [[1,2,3], [4,5,6], [7,8,9]]} json_contains(x, [1,2,3]) # ==> true json_contains(x, [3,2,1]) # ==> false
JSON_CONTAINS_ALL(identifier, JsonExpr)
JSON_CONTAINS_ALL
语句中的 JSON 表达式应始终为 list。# {"x": [1,2,3,4,5,7,8]} json_contains_all(x, [1,2,8]) # ==> true json_contains_all(x, [4,5,6]) # ==> false 6 is not exists
JSON_CONTAINS_ANY(identifier, JsonExpr)
JSON_CONTAINS_ANY
语句中的 JSON 表达式应始终为 list。否则,其作用与JSON_CONTAINS
相同。# {"x": [1,2,3,4,5,7,8]} json_contains_any(x, [1,2,8]) # ==> true json_contains_any(x, [4,5,6]) # ==> true json_contains_any(x, [6,9]) # ==> false
- 数组表达式
ARRAY_CONTAINS(identifier, ArrayExpr)
如果
ARRAY_CONTAINS
(第二个参数)语句的数组表达式是一个 list,则标识符(第一个参数)应为 list 的 list。否则,语句的值总是 False。# 'int_array': [1,2,3] array_contains(int_array, 1) # ==> true array_contains(int_array, "a") # ==> false
ARRAY_CONTAINS_ALL(identifier, ArrayExpr)
ARRAY_CONTAINS_ALL
语句中的数组表达式应始终为 list。# "int_array": [1,2,3,4,5,7,8] array_contains_all(int_array, [1,2,8]) # ==> true array_contains_all(int_array, [4,5,6]) # ==> false 6 is not exists
ARRAY_CONTAINS_ANY(identifier, ArrayExpr)
ARRAY_CONTAINS_ANY
语句中的数组表达式应始终为 list。否则,其作用与ARRAY_CONTAINS
相同。# "int_array": [1,2,3,4,5,7,8] array_contains_any(int_array, [1,2,8]) # ==> true array_contains_any(int_array, [4,5,6]) # ==> true array_contains_any(int_array, [6,9]) # ==> false
ARRAY_LENGTH(identifier)
检查数组中的元素个数。
# "int_array": [1,2,3,4,5,7,8] array_length(int_array) # ==> 7
下一步
既然你已经知道比特集在 Milvus 中是如何工作的,你可能还想
- 学习如何进行混合搜索。
- 学习如何使用字符串过滤搜索结果。
- 学习如何在构建布尔表达式时使用Dynamic Field。