标量过滤规则

概述

谓词表达式输出一个布尔值。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 即二进制操作符,对两个操作数进行操作。在包含两个或多个操作数的复杂表达式中,运算顺序取决于优先级规则。
CmpOpCmpOp 是对两个操作数进行操作的关系运算符。
CmpOpRestrictedCmpOpRestricted 仅限于 "小于 "和 "等于"。
常量表达式ConstantExpr 可以是一个常量,也可以是两个 ConstantExpr 上的二元 ArithOp 或单个 ConstantExpr 上的一元 ArithOp。它是递归定义的。
常量数组ConstantArray 用方括号封装,ConstantExpr 可以在方括号中重复出现。ConstArray 必须至少包含一个 ConstantExpr。
TermExprTermExpr 用于检查 IDENTIFIER 的值是否出现在 ConstantArray 中。TermExpr 用 "in "表示。
比较表达式CompareExpr 即比较表达式,可以是对两个 IDENTIFIER 的关系操作,也可以是对一个 IDENTIFIER 和一个 ConstantExpr 的关系操作,还可以是对两个 ConstantExpr 和一个 IDENTIFIER 的三元操作。
单表达式SingleExpr 即单一表达式,可以是 TermExpr 或 CompareExpr。
逻辑表达式LogicalExpr 可以是两个 LogicalExpr 上的二进制逻辑操作(BinaryLogicalOp),也可以是单个 LogicalExpr 上的一元逻辑操作(UnaryLogicalOp),还可以是括号内分组的 LogicalExpr 或 SingleExpr。LogicalExpr 是递归定义的。
ExprExpr 是表达式的缩写,可以是 LogicalExpr 或 NIL。
匹配运算符MatchOp 即匹配操作符,用于将字符串与字符串常量或字符串前缀、后缀或后缀常量进行比较。
JsonArrayOpJsonOp 即 JSON 操作符,用于检查指定标识符是否包含指定元素。
ArrayOpArrayOp 即数组操作符,用于检查指定标识符是否包含指定元素。

操作符

逻辑操作符

逻辑操作符在两个表达式之间进行比较。

符号操作符示例说明
和' &&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像 LIKEMatchOp从左至右
9json_contains JSON_CONTAINSJsonArrayOp从左至右
9array_contains ARRAY_CONTAINSArrayOp从左至右
10json_contains_all JSON_CONTAINS_ALLJsonArrayOp从左至右
10array_contains_all ARRAY_CONTAINS_ALLArrayOp从左至右
11json_contains_any JSON_CONTAINS_ANYJsonArrayOp从左至右
11array_contains_any ARRAY_CONTAINS_ANYArrayOp从左至右
12array_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 类型数据的标量字段):

  1. CmpOp
"int64 > 0"
"0 < int64 < 400"
"500 <= int64 < 1000"
VARCHAR > "str1"
  1. BinaryLogicalOp 和括号
"(int64 > 0 && int64 < 400) or (int64 > 500 && int64 < 1000)"
  1. TermExpr 和 UnaryLogicOp
"int64 not in [1, 2, 3]"
VARCHAR not in ["str1", "str2"]
  1. TermExpr、BinaryLogicalOp 和 CmpOp(在不同字段上)
"int64 in [1, 2, 3] and float != 2"
  1. BinaryLogicalOp 和 CmpOp
"int64 == 0 || int64 == 1 || int64 == 2"
  1. CmpOp 和 UnaryArithOp 或 BinaryArithOp
"200+300 < int64 <= 500+500"
  1. MatchOp
VARCHAR like "prefix%"
VARCHAR like "%suffix"
VARCHAR like "%middle%"
VARCHAR like "_suffix"
  1. 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
    
  1. 数组表达式
  • 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 中是如何工作的,你可能还想

想要更快、更简单、更好用的 Milvus SaaS服务 ?

Zilliz Cloud是基于Milvus的全托管向量数据库,拥有更高性能,更易扩展,以及卓越性价比

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?