iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
1
Elastic Stack on Cloud

Elastic Stack武學練功坊系列 第 20

Elastic Stack第二十重

  • 分享至 

  • xImage
  •  

Search and Query DSL Part I (搜尋和查詢語法)

這篇前半段會先補充search中的 Track total hits
後半段會開始介紹 Query DSL的 Full text queries,不過這部分會分幾篇來一一說明


Search

補充一些之前search章節未提及的

Track total hits
一般而言,計算total hits(總數)需要拜訪很多documents,因而比較耗資源,
實際上,總數不一定會 "等於" hits.total.value ,有可能只是 "lower bound(下界)",

可以透過 track_total_hits 參數來控制總數的追蹤,
預設值是 10000,也就是當你搜尋匹配的documents超過10000時, hits.total.value 值只會是 10000 ,不過可以透過 hits.total.relation 來查看是 "lower bound" 還是 "等於",
如果是 "eq" 即為 "等於" , 如果是 "gte" 即為 "lower bound"

track_total_hits 設為 true 時,es回傳的 hits.total.value 值就都會是總數值,
hits.total.relation 也一定會是 "eq" ,因為 回傳的值都是總數值,已沒有下界的限制

如果真不需要總數,也可以把 track_total_hits 設為 false ,此時就不會有 hits.total

設定方式可參閱下方範例,範例使用 Elastic Stack第七重 匯入的範例資料,如欲使用此匯入資料可以先照那一重做批次匯入

track_total_hits 使用預設值

GET /bank/_search
{
  "query": {
    "match_all": {}
  }
}

Response
Response
因為在還未設定 track_total_hits ,所以目前是預設值 10000
hits.total.relation"eq"hits.total.value1000 ,代表總是就是等於 1000

track_total_hits 設定為 "500"

GET /bank/_search
{
  "query": {
    "match_all": {}
  },
  "track_total_hits": "500"
}

Response
Response
因為 track_total_hits 設為 "500",代表 lower bound 就是 500
而response中的 hits.total.relation"gte"hits.total.value500
就代表著 實際的總數 超過500,但因為有 lower bound 設定所以沒有顯示實際總數

Full text queries

full text queries 可以用來搜尋 text fields,
預設情況下, query string (搜尋的字串) 會和 field value 使用相同的 analyzer

總共有以下幾種:

  • intervals query
  • match query
  • match_bool_prefix query
  • match_phrase query
  • match_phrase_prefix query
  • multi_match query
  • common terms query
  • query_string query
  • simple_query_string query

我不會依照上面順序介紹,比較傾向由簡單介紹到複雜的,而且預計用幾篇來一一介紹

match query
是個標準full-text search的query

直接用範例解釋

Request

GET /_search
{
  "query": {
    "match": { (1)
      "message": { (2)
        "query": "this is a test" (3)
      }
    }
  }
}

(1): 即為 match query
(2): message <field> ,是 match 的 top-level參數,是必填
(3): query<field> 的必填參數, "this is a test" 即為 query value

依照上述 Request ,會匹配到 message field中,有 thisisatest
也就是說此 query value可以解析為 this OR is OR a OR test

<field> 下的參數,也就是和 query 同層的,還有很多參數,
其中我以 operatorminimum_should_match 多加說明

其實, match query 是屬於 boolean 類型,意思是,
提供的 query value 經過 analyzer 分析過後,會產生 boolean query
而參數 operator 就是可以來控制 boolean clauses要用 or 還是 and (預設是 or)
參數 minimum_should_match 可設定 should clauses 最少需匹配的數量

上述的範例,即 operatororminimum_should_match1

[補充]
match query 支援縮寫的方式,把 <field>query的值(query value)結合,
可把上述範例縮寫成如下寫法

GET /_search
{
  "query": {
    "match": {
      "message": "this is a test"
    }
  }
}

match_bool_prefix query
match query一樣, match_bool_prefix 也可以分析 query value後,
從產生的terms建構出 bool qeury,而除了最後一個term之外,都是使用 term query,最後一個term是使用 prefix query

舉個例

Request

GET /_search
{
  "query": {
    "match_bool_prefix" : {
      "message" : "quick brown f"
    }
  }
}

此 query value會產生出的terms為 quick , brown , f
透過這些terms建構出的 bool query 會長得如下

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {"term": {"message": "quick"}},
        {"term": {"message": "brown"}},
        {"prefix": {"message": "f"}}
      ]
    }
  }
}

拆解成上述其實就很明瞭,不過還是要注意,should內的三個query clauses是沒有順序的,意即,brown fox quick 是可以被匹配得到的
此外,如 match 一樣,預設為 or,所以其實 quickbrown 甚至是只要是 f開頭的字串,只要有這三種任一個有匹配到即可


小小新手,如有理解錯誤或寫錯再請不吝提醒或糾正


Reference

Track total hit
Full text queries


上一篇
Elastic Stack第十九重
下一篇
Elastic Stack第二十一重
系列文
Elastic Stack武學練功坊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言