Elasticsearch查詢——布爾查詢Bool Query

Elasticsearch在2.x版本的時候把filter查詢給摘掉了,所以在query dsl裏面已經找不到filter query了。其實es並無徹底拋棄filter query,而是它的設計與以前的query過重複了。所以直接給轉移到了bool查詢中。html

Bool查詢如今包括四種子句,must,filter,should,must_not。緩存

爲何filter會快?

看上面的流程圖就能很明顯的看到,filter與query仍是有很大的區別的。elasticsearch

好比,query的時候,會先比較查詢條件,而後計算分值,最後返回文檔結果;ide

而filter則是先判斷是否知足查詢條件,若是不知足,會緩存查詢過程(記錄該文檔不知足結果);知足的話,就直接緩存結果。ui

綜上所述,filter快在兩個方面:設計

  • 1 對結果進行緩存
  • 2 避免計算分值

bool查詢的使用

Bool查詢對應Lucene中的BooleanQuery,它由一個或者多個子句組成,每一個子句都有特定的類型。code

must

返回的文檔必須知足must子句的條件,而且參與計算分值htm

filter

返回的文檔必須知足filter子句的條件。可是不會像Must同樣,參與計算分值blog

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"
            }
        }
    }
}

參考

1 bool查詢
2 《Elasticsearch IN Action》

相關文章
相關標籤/搜索