Elasticsearch查詢——布林查詢Bool Query
Elasticsearch在2.x版本的時候把filter查詢給摘掉了,因此在query dsl裡面已經找不到filter query了。其實es並沒有完全拋棄filter query,而是它的設計與之前的query太重複了。因此直接給轉移到了bool查詢中。
Bool查詢現在包括四種子句,must,filter,should,must_not。
為什麼filter會快?
看上面的流程圖就能很明顯的看到,filter與query還是有很大的區別的。
比如,query的時候,會先比較查詢條件,然後計算分值,最後返回文件結果;
而filter則是先判斷是否滿足查詢條件,如果不滿足,會快取查詢過程(記錄該文件不滿足結果);滿足的話,就直接快取結果。
綜上所述,filter快在兩個方面:
- 1 對結果進行快取
- 2 避免計算分值
bool查詢的使用
Bool查詢對應Lucene中的BooleanQuery,它由一個或者多個子句組成,每個子句都有特定的型別。
must
返回的文件必須滿足must子句的條件,並且參與計算分值
filter
返回的文件必須滿足filter子句的條件。但是不會像Must一樣,參與計算分值
should
返回的文件可能滿足should子句的條件。在一個Bool查詢中,如果沒有must或者filter,有一個或者多個should子句,那麼只要滿足一個就可以返回。minimum_should_match
引數定義了至少滿足幾個子句。
must_nout
返回的文件必須不滿足must_not定義的條件。
如果一個查詢既有filter又有should,那麼至少包含一個should子句。
bool查詢也支援禁用協同計分選項disable_coord。一般計算分值的因素取決於所有的查詢條件。
bool查詢也是採用more_matches_is_better的機制,因此滿足must和should子句的文件將會合並起來計算分值。
{ "bool" : { "must" : { "term" : { "user" : "kimchy" } }, "filter": { "term" : { "tag" : "tech" } }, "must_not" : { "range" : { "age" : { "from" : 10, "to" : 20 } } }, "should" : [ { "term" : { "tag" : "wow" } }, { "term" : { "tag" : "elasticsearch" } } ], "minimum_should_match" : 1, "boost" : 1.0 } }
bool.filter的分值計算
在filter子句查詢中,分值將會都返回0。分值會受特定的查詢影響。
比如,下面三個查詢中都是返回所有status欄位為active的文件
第一個查詢,所有的文件都會返回0:
GET _search
{
"query": {
"bool": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}
下面的bool查詢中包含了一個match_all,因此所有的文件都會返回1
GET _search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"status": "active"
}
}
}
}
}
constant_score與上面的查詢結果相同,也會給每個文件返回1:
GET _search
{
"query": {
"constant_score": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}
使用named query給子句新增標記
如果想知道到底是bool裡面哪個條件匹配,可以使用named query查詢:
{
"bool" : {
"should" : [
{"match" : { "name.first" : {"query" : "shay", "_name" : "first"} }},
{"match" : { "name.last" : {"query" : "banon", "_name" : "last"} }}
],
"filter" : {
"terms" : {
"name.last" : ["banon", "kimchy"],
"_name" : "test"
}
}
}
}