iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
1
Elastic Stack on Cloud

Elastic Stack武學練功坊系列 第 26

Elastic Stack第二十六重

  • 分享至 

  • xImage
  •  

Query DSL Part VII (查詢語法)

本篇繼續介紹 Query DSL 的 term-lvel queries


range query

找出terms在指定的range的documents

[情境] 找出 field age 的field value 介於 10(包含) 和 20(包含) 之間的documents
Example Request

GET /_search
{
  "query": {
    "range": { (1)
      "age": { (2)
        "gte": 10, (3)
        "lte": 20 (4)
      }
    }
  }
}

(1): range query
(2): <field>,必填,欲搜尋的 field
(3): gte,大於等於
(4): lte,小於等於

當然,有大於等於,也有 "大於",使用 gt,同理,"小於" 使用 lt

range query with text and keyword fields
實際上,range query是可以用在 field type為 textkeyword 的fields,
不過是屬於 expensive queries (成本比較高),所以一般而言執行會比較慢。
而有參數可以限制 expensive queriessearch.allow_expensive_queries 預設為 true
當設定為 false 時,就無法執行 expensive queries,也就會包含無法使用 range query 來搜尋 field data type 為 textkeyword 的fields。

range query with date fields
如果 <field> 的 field data type為 date,則可以使用 date math(https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math) 搭配 gt, gte, lt, lte

[情境] 找出 field timestamp 的field value 介於 今天 和 昨天 之間的documents
Example Request

GET /_search
{
  "query": {
    "range": {
      "timestamp": {
        "gte": "now-1d/d", (1)
        "lt": "now/d" (2)
      }
    }
  }
}

(1): 現在 減 1天,並無條件捨去至最近的天
(2): 現在,並無條件捨去至最近的天

這邊稍微說明一下 date math
可使用日期來當錨點(anchor),如 now 或者是 formatted date,而如果使用 formatted date,其後面須加上 ||,然後在 anchor date 後面可選擇性加上 數學式,
例如:

  • +1h: 加上1小時
  • -1d: 減1天
  • /d: 無條件捨去至最近的天

regex query

透過 regular expression 找出有匹配的terms,然後回傳其documents

regex query 支援的operators可參閱 Regular expression syntax ,是使用 Apache Lucene's 的 regular expression 引擎

[情境] 找出field user.idk 開頭,y 結尾的documents
Example Request

GET /_search
{
  "query": {
    "regexp": { (1)
      "user.id": { (2)
        "value": "k.*y", (3)
        "flags": "ALL" (4)
      }
    }
  }
}

(1): 即 regex query
(2): <field>,必填,欲搜尋的 field
(3): value,必填,填入 regular expression
(4): flags,選填,預設為 ALL,此參數用來設定 regular expression引擎 可使用的operators

上述request的 regex為 "k.*y",其中 .* operators 代表的是可以匹配任何字元,包括沒有字元也算,所以可以匹配的terms可以是 ky, kay, kelly 等等

[Note]
regex query也是屬於 expensive queries


term query

搜尋出指定field含 exact term 的documents

在蠻多篇章應該都有提到此 query,這邊再完整介紹一次

[Note]
避免使用 term query 在 text field 上,因為 text field在建立索引時,會經過 analyzer分析而改變原本的值,所以會讓精確匹配是很困難的

此範例使用 Elastic Stack第七重 匯入的範例資料,所以想用一樣的測資可先照那一重做批次匯入

[情境] 找出 field firstname"Nanette" 的 帳戶擁有者資訊(document)
Request

GET /bank/_search
{
  "query": {
    "term": { (1)
      "firstname.keyword": { (2)
        "value": "Nanette" (3)
      }
    }
  }
}

(1): 即 term query
(2): <field>,必填,欲搜尋的field,記得使用非 text field,此處使用 "firstname.keyword" 的 field date type為 keyword,而 "firstname"text field data type,所以不能使用 "firstname" ,否則會不如預期(以此為例,用 "firstname" 會匹配不到任何documents)
(3): value,必填,欲搜尋的值

Response
Response

上述Request也可以簡寫成

GET /bank/_search
{
  "query": {
    "term": {
      "firstname.keyword": "Nanette"
    }
  }
}

[Note]
如欲搜尋 text fields,可以透過 match query,在儲存至此field前會經過analyzer分析後轉換成tokens才會被建立索引,而用 match query 提供的 query string(search term)也一樣會經過analyzer分析,此兩個analyzer是可以指定成不一樣的analyzer,在未設定時,皆使用預設的 standard analyzer ,透過分析後的 tokens 來做匹配搜尋,而不是用 exact term(精確的值)

term query "不會"分析 search term, term query 直接拿提供的term找出完整符合的term,這也意味著用 term query 搜尋 text fields 可能回傳 poor(較少) 或 沒有匹配的documents


terms query

搜尋出指定field含 一個或多個 exact term 的documents,
其實和 term query一樣,只是差在可以搜尋多個值

[情境] 找出 field firstname"Nanette""Mcgee" 的 帳戶擁有者資訊(document)
Request

GET /bank/_search
{
  "query": {
    "terms": { (1)
      "firstname.keyword": ["Nanette", "Mcgee"] (2)
    }
  }
}

(1): 即 terms query
(2): 放置多個 search term至array value

Response
Response


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


Reference

Term-level queries
regular expression


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

尚未有邦友留言

立即登入留言