标量过滤规则
概述
谓词表达式输出一个布尔值。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]) # ==> falseJSON_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 existsJSON_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") # ==> falseARRAY_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 existsARRAY_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]) # ==> falseARRAY_LENGTH(identifier)检查数组中的元素个数。
# "int_array": [1,2,3,4,5,7,8] array_length(int_array) # ==> 7
下一步
现在你知道了比特集在 Milvus 中是如何工作的,你可能还想
- 学习如何进行混合搜索。
- 学习如何使用字符串过滤搜索结果。
- 学习如何在构建布尔表达式时使用 Dynamic Field。