標量篩選規則
概述
謂語表達式輸出一個布林值。Milvus 透過謂語搜尋進行標量值篩選。謂語表達式在求值時會返回 TRUE 或 FALSE。請參閱Python SDK API Reference,以取得使用謂語表達式的說明。
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 } "]";
下表列出上述布林表達式規則中提到的每個符號的說明。
| 符號 | 說明 |
|---|---|
| = | 定義。 |
| , | 連接。 |
| ; | 終止。 |
| | | 交替。 |
| {...} | 重複。 |
| (...) | 組合。 |
| 無 | 空。表達式可以是空字串。 |
| INTEGER | 整數,例如 1、2、3。 |
| 浮點數 | 浮點數,例如 1.0、2.0。 |
| CONST | 整數或浮點數。 |
| IDENTIFIER | 識別碼。在 Milvus 中,IDENTIFIER 代表欄位名稱。 |
| 邏輯運算 | LogicalOp 是一個邏輯運算符號,支援在一次比較中結合多個關係運算。LogicalOp 的回傳值是 TRUE (1) 或 FALSE (0)。邏輯操作有兩種類型,包括二元邏輯操作 (BinaryLogicalOps) 和單元邏輯操作 (UnaryLogicalOps)。 |
| 單值邏輯操作 | UnaryLogicalOp 指單元邏輯運算符號 "not"。 |
| 二進制邏輯運算符號 | 對兩個操作數執行動作的二進制邏輯運算符。在具有兩個或更多操作數的複雜表達式中,評估的順序取決於優先順序規則。 |
| 算術運算 | ArithmeticOp 即算术运算符,对操作数执行加法和减法等数学运算。 |
| 單值運算符號 | UnaryArithOp 是一種算術運算元,可在單一操作數上執行運算。負數 UnaryArithOp 會將正數表達式變為負數表達式,反之亦然。 |
| 二進制 ArithOp | BinaryArithOp 即二元運算符號,可在兩個操作數上執行運算。在具有兩個或更多操作數的複雜表達式中,運算順序取決於優先順序規則。 |
| CmpOp | CmpOp 是對兩個操作數執行操作的關聯運算符。 |
| CmpOpRestricted | CmpOpRestricted 限於 "Less than「 和 」Equal"。 |
| 常數Expr | ConstantExpr 可以是常量或兩個 ConstantExpr 上的 BinaryArithOp 或單一 ConstantExpr 上的 UnaryArithOp。它是遞迴定義的。 |
| 常數陣列 | ConstantArray 由方括弧包圍,ConstantExpr 可以重複出現在方括弧中。ConstArray 必須包含至少一個 ConstantExpr。 |
| TermExpr | TermExpr 用來檢查 IDENTIFIER 的值是否出現在 ConstantArray 中。TermExpr 用 "in" 表示。 |
| CompareExpr | CompareExpr 即比較表達式,可以是兩個 IDENTIFIER 上的關聯操作,或一個 IDENTIFIER 和一個 ConstantExpr 上的關聯操作,或兩個 ConstantExpr 和一個 IDENTIFIER 上的三元操作。 |
| 單一表達式 | SingleExpr 即單一表達式,可以是 TermExpr 或 CompareExpr。 |
| 邏輯表 達式 | LogicalExpr 可以是兩個 LogicalExpr 上的 BinaryLogicalOp,或是單一 LogicalExpr 上的 UnaryLogicalOp,或是在括弧中組合的 LogicalExpr,或是 SingleExpr。LogicalExpr 是遞迴定義的。 |
| Expr | Expr 是表示表達式的縮寫,可以是 LogicalExpr 或 NIL。 |
| MatchOp | MatchOp 即匹配運算符號,用來比較字串與字串常數或字串前綴、後綴或後綴常數。 |
| JsonArrayOp | 一個 JsonOp,即 JSON 運算子,檢查指定的識別碼是否包含指定的元素。 |
| ArrayOp | 一個 ArrayOp,即一個陣列運算元,檢查指定的識別碼是否包含指定的元素。 |
運算符號
邏輯運算符號
邏輯運算符號執行兩個表達式之間的比較。
| 符號 | 運算符號 | 範例 | 說明 |
|---|---|---|---|
| 'and' && | 和 | expr1 && expr2 | 如果 expr1 和 expr2 都為真,則為真。 |
| 'or' || | 或 | expr1 || expr2 | 如果 expr1 或 expr2 均為真,則為 True。 |
二進位算術運算元
二進位算術運算元包含兩個操作數,可以執行基本算術運算並傳回相對應的結果。
| 符號 | 運算 | 範例 | 說明 |
|---|---|---|---|
| + | 加法 | a + b | 將兩個操作數相加。 |
| - | 減法 | a - b | 從第一個操作數減去第二個操作數。 |
| * | 乘法 | a * b | 將兩個操作數相乘 |
| / | 除法 | a / b | 用第一個操作數除以第二個操作數。 |
| ** | 幂 | a ** b | 將第一個作業數提升為第二個作業數的幂。 |
| % | 模數 | a % b | 將第一個作業數除以第二個作業數,得出餘數部分。 |
關係運算符號
關係運算符使用符號來檢查兩個表達式之間的相等、不等或相對順序。
| 符號 | 運算 | 範例 | 說明 |
|---|---|---|---|
| < | 小於 | a < b | 如果 a 小於 b,則為 True。 |
| > | 大於 | a > b | True 如果 a 大於 b。 |
| == | 相等 | a == b | 如果 a 等於 b,則為 True。 |
| != | 不相等 | a != b | 如果 a 不等於 b,則為 True。 |
| <= | 小於或相等 | a <= b | True 如果 a 小於或等於 b。 |
| >= | 大於或等於 | a >= b | 如果 a 大於或等於 b,則為 True。 |
運算符號的先後次序和關聯性
下表列出運算符號的優先順序和關聯性。運算符號從上至下依序排列。
| 優先順序 | 運算符號 | 說明 | 關聯性 |
|---|---|---|---|
| 1 | + - | 單值運算符號 | 從左至右 |
| 2 | 非 | 單元逻辑Op | 從右至左 |
| 3 | ** | 二進制 ArithOp | 從左至右 |
| 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 | || 或 | 二進制LogicOp | 從左至右 |
表達式通常從左至右求值。複雜的表達式會一次求值一個。表達式的求值順序由所用運算符的優先順序決定。
如果一個表達式包含兩個或兩個以上具有相同優先順序的運算符號,則會先對左側的運算符號進行求值。
例如,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
下一步
現在您知道 bitsets 在 Milvus 中是如何工作的了,您可能還想
- 學習如何進行混合搜尋。
- 學習如何使用字串過濾搜尋結果。
- 學習如何在建立布林表達式時使用動態欄位。