1、布爾過濾器
前篇文章中(term精確查找)的兩個例子都是單個過濾器(filter)的使用方式。 在實際應用中,我們很有可能會過濾多個值或字段。比方說,怎樣用 Elasticsearch 來表達下面的 SQL ?
這種情況下,我們需要 bool
(布爾)過濾器。 這是個 復合過濾器(compound filter) ,它可以接受多個其他過濾器作為參數,並將這些過濾器結合成各式各樣的布爾(邏輯)組合。
一個 bool
過濾器由三部分組成:
-
must
-
所有的語句都
必須(must) 匹配,與
AND
等價。 -
must_not
-
所有的語句都
不能(must not) 匹配,與
NOT
等價。 -
should
-
至少有一個語句要匹配,與
OR
等價。
只須將它們置入 bool
過濾器的不同部分即可,一個 bool
過濾器的每個部分都是可選的(例如,我們可以只有一個 must
語句),而且每個部分內部可以只有一個或一組過濾器。
用 Elasticsearch 來表示本部分開始處的 SQL 例子,將兩個 term
過濾器置入 bool
過濾器的 should
語句內,再增加一個語句處理 NOT
非的條件:
GET /my_store/products/_search { "query" : { "bool" : { "should" : [ { "term" : {"price" : 20}}, { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} ], "must_not" : {"term" : {"price" : 30} } } } }
在 should
語句塊里面的兩個 term
過濾器與 bool
過濾器是父子關系,兩個 term
條件需要匹配其一。
如果一個產品的價格是 30
,那么它會自動被排除,因為它處於 must_not
語句里面。
結果返回了 2 個命中結果,兩個文檔分別匹配了 bool
過濾器其中的一個條件
2、嵌套布爾過濾器
盡管 bool
是一個復合的過濾器,可以接受多個子過濾器,需要注意的是 bool
過濾器本身仍然還只是一個過濾器。 這意味着我們可以將一個 bool
過濾器置於其他 bool
過濾器內部,
這為我們提供了對任意復雜布爾邏輯進行處理的能力。
對於以下這個 SQL 語句:
我們將其轉換成一組嵌套的 bool
過濾器:
GET /my_store/products/_search { "query" : { "bool" : { "should" : [ { "term" : {"productID" : "XHDK-A-1293-#fJ3"}}, { "bool" : { "must" : [ { "term" : {"productID" : "JODL-X-1937-#pV7"}}, { "term" : {"price" : 30}} ] } } ] } } }
因為 term
和 bool
過濾器是兄弟關系,他們都處於外層的布爾邏輯 should
的內部,返回的命中文檔至少須匹配其中一個過濾器的條件。
這兩個 term
語句作為兄弟關系,同時處於 must
語句之中,所以返回的命中文檔要必須都能同時匹配這兩個條件。