ElasticSearch查詢 第五篇:布爾查詢


《ElasticSearch查詢》目錄導航:

 

布爾查詢是最常用的組合查詢,不僅將多個查詢條件組合在一起,並且將查詢的結果和結果的評分組合在一起。當查詢條件是多個表達式的組合時,布爾查詢非常有用,實際上,布爾查詢把多個子查詢組合(combine)成一個布爾表達式,所有子查詢之間的邏輯關系是與(and);只有當一個文檔滿足布爾查詢中的所有子查詢條件時,ElasticSearch引擎才認為該文檔滿足查詢條件。布爾查詢支持的子查詢類型共有四種,分別是:must,should,must_not和filter:

  • must子句:文檔必須匹配must查詢條件;
  • should子句:文檔應該匹配should子句查詢的一個或多個;
  • must_not子句:文檔不能匹配該查詢條件;
  • filter子句:過濾器,文檔必須匹配該過濾條件,跟must子句的唯一區別是,filter不影響查詢的score;

通常情況下,should子句是數組字段,包含多個should子查詢,默認情況下,匹配的文檔必須滿足其中一個子查詢條件。如果查詢需要改變默認匹配行為,查詢DSL必須顯式設置布爾查詢的參數minimum_should_match的值,該參數控制一個文檔必須匹配的should子查詢的數量,我遇到一個布爾查詢語句,其should子句中包含兩個查詢,如果不設置參數minimum_should_match,其默認值是0。建議在布爾查詢中,顯示設置參數minimum_should_match的值。

注:布爾查詢的四個子句,都可以是數組字段,因此,支持嵌套邏輯操作的查詢。

例如,對於以下should查詢,一個文檔必須滿足should子句中兩個以上的詞條查詢:

"should" : [
        {  "term" : { "tag" : "azure" } },
        {  "term" : { "tag" : "elasticsearch" } },
        {  "term" : { "tag" : "cloud" } }
    ],
"minimum_should_match" : 2

布爾查詢的各個子句之間的邏輯關系是與(and),這意味着,一個文檔只有同時滿足所有的查詢子句時,該文檔才匹配查詢條件,作為結果返回。

在布爾查詢中,對查詢結果的過濾,建議使用過濾(filter)子句和must_not子句,這兩個子句屬於過濾上下文(Filter Context),經常使用filter子句,使得ElasticSearch引擎自動緩存數據,當再次搜索已經被緩存的數據時,能夠提高查詢性能;由於過濾上下文不影響查詢的評分,而評分計算讓搜索變得復雜,消耗更多CPU資源,因此,filter和must_not查詢減輕搜索的工作負載。

一,查詢和過濾上下文

在布爾查詢中,查詢被分為Query Context 和 Filter Context,查詢上下文由query參數指定,過濾上下文由filter和must_not參數指定。這兩個查詢上下文的唯一區別是:Filter Context不影響查詢的評分(score)。在布爾查詢中,Filter參數和must_not參數使用Filter Context,而must和should使用Query Context,經常使用Filter Context,引擎會自動緩存數據,提高查詢性能。

GET _search
{
  "query": { 
    "bool": { 
      "must": [
        { "match": { "title":   "Search"        }}, 
        { "match": { "content": "Elasticsearch" }}  
      ],
      "filter": [ 
        { "term":  { "status": "published" }}, 
        { "range": { "publish_date": { "gte": "2015-01-01" }}} 
      ]
    }
  }
}

對於上述查詢請求,must子句處於query context中,filter子句處於filter context中:

  • 在query context中,must子句將返回同時滿足匹配(match)查詢的文檔;
  • 在filter context中,filter子句是一個過濾器,將不滿足詞條查詢和范圍查詢條件的文檔過濾掉,並且不影響匹配文檔的score;

二,布爾查詢子句的邏輯關系

在布爾查詢中,各個子句之間的邏輯關系是與(and)。對於單個子句,只要一個文檔滿足該子句的查詢條件,返回的邏輯結果就是true,而對於should子句,它一般包含多個子查詢條件,參數 minimum_should_match 控制文檔必須滿足should子句中的子查詢條件的數量,只有當文檔滿足指定數量的should查詢條件時,should子句返回的邏輯結果才是true。

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

在上述布爾查詢中,should子句中包含兩個詞條查詢,由於參數 minimum_should_match的值是1,因此,只要一個穩定滿足任意一個詞條查詢的條件,should子句就匹配成功,返回邏輯結果true,然后和其他子查詢進行邏輯運算,只有當該文檔滿足所有的子查詢條件時,才作為查詢結果返回到客戶端。

三,布爾查詢示例分析

1,使用布爾查詢實現簡單的邏輯查詢

在下述示例中,分析布爾查詢的運算邏輯:

  • must子句和should子句之間的邏輯關系是and;
  • must子句包含一個匹配查詢,字段eventname必須包含style詞條;
  • should子句是一個數組,包含兩個匹配查詢,文檔必須匹配的子句查詢條件數量由參數 minimum_should_match控制;
  • 參數 minimum_should_match的值是1,這就意味着,一個文檔只要滿足任意一個查詢子句,就匹配should子句;
{  
   "query":{  
      "bool":{  
         "must":{  
            "match":{  "eventname":"style" }
         },
         "should":[  
            { "match":{ "eventname":"google" } },
            { "match":{  "eventname":"aws" }}
         ],
         "minimum_should_match":1
      }
   }
}

通過上述分析,以下字段值滿足查詢條件:

  • "eventname": "Google style map"
  • "eventname": "AWS Game Day ~ Seattle Style!"

2,使用布爾查詢實現復雜的分組查詢

復雜的分組查詢,例如:(A and B) or (C and D) or (E and F) ,把布爾查詢作為should子句的一個子查詢:

{
  "_source": "topics",
  "from": 0,
  "size": 100,
  "query": {
    "bool": {
      "should": [
       {
          "bool": {
            "must": [
              { "term": { "topics": 1}  },
              { "term": { "topics": 2}  }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {"term": { "topics": 3 } },
              {"term": { "topics": 4}}
            ]
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

 

 

參考文檔:

Elasticsearch Reference [2.4] » Query DSL » Compound queries » Bool Query


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM