iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
1
Elastic Stack on Cloud

Elastic Stack武學練功坊系列 第 22

Elastic Stack第二十二重

  • 分享至 

  • xImage
  •  

Query DSL Part III (查詢語法)

本篇繼續介紹 Query DSL的 Full text queries


本篇介紹以下 full text queries

  • query_string query
  • simple_query_string query
  • intervals query (基本概念介紹)
  • common query (基本概念介紹)

query_string query
query string 透過 "strict syntax(嚴格的語法)" 的parser來解析,
會先依據 operators 來 split(切分) query string, operators 像是 AND , OR , NOT
然後再一個一個 analyzes(分析) split text(切分的字串),之後才會去最匹配的動作

可以透過 query_string 來做到很複雜的搜尋,包含 使用wildcard 或 搜尋多個fields 等等,
但是 query是比較嚴格的,只要有無效的語法就會回傳錯誤,也因此官方也說明 query string 不建議拿來使用在 "search box(搜尋框)"

Example Request

GET /_search
{
  "query": {
    "query_string": {
      "query": "(new york city) OR (big apple)", (1)
      "default_field": "content" (2)
    }
  }
}

(1): 必填,欲用來搜尋的 query string
(2): 選填,如果 query string 沒有指定 field,就會使用此 default_field 的 field 來搜尋,如 default_field 也未提供,會使用index的設定 index.query.default_field ,而此設定預設是 ** 指的是所有fields中可支援 term query 的fields

解析上述Request會如何parse
會把 query string 拆解成 new york citybig apple 兩部份,
而這兩部份一一被 content field 的 analyzer 轉成 tokens,然後才去做匹配的動作

[指定fields]
此外,可以直接在 query string 中指定 用某一字串搜尋特定fields,
例如: status:active 搜尋 status field 是否包含 active
title:(quick OR brown) 搜尋 title field 是否包含 quickbrown
author:"John Smith" 搜尋 author 要包含 phrase "John Smith"

[範圍(range)]
range 可用在 date, numeric, string等等,其中使用
中括號 [min TO max] 代表有包含邊界值,使用大括號 {min TO max} 則不包含邊界值
例如: date:[2012-01-01 TO 2012-12-31] 搜尋 date field 2012的每一天
date:{* TO 2012-01-01} 搜尋 date field 2012以前的所有日期(不包括2012-01-01)
也可以並用中大括號, count:[1 TO 5} 搜尋 count field 數值1(包含) 至 5(不包含)

query_string query 功能很複雜很多樣,但也比較嚴格,如上述所說,只要語法是無效的就會報錯,
官方文件也提及此query適合給 "專業使用者"

simple_query_string query
query string 透過 "有限制可容錯" 的parser來解析,
根據 special operators 把 query string 切分成 terms
simple_query_string 不會因為無效的語法而報錯,他會忽略他

Example Request

GET /_search
{
  "query": {
    "simple_query_string" : {
        "query": "\"fried eggs\" +(eggplant | potato) -frittata", (1)
        "fields": ["title^5", "body"], (2)
        "default_operator": "and" (3)
    }
  }
}

(1): 必填,即 query string
(2): 選填,欲搜尋的 fields (可多個), 其中 ^5,代表著 title 權重是 body 的5倍
(3): 選填,在 query string 中,如果沒有指定 operators ,則會使用此 default_operator 設定的operator, default_operator 可填的值有 ORANDdefault_operator 預設值為 OR

simple_query_string 支援的operators有:

  • + 代表 AND 動作
  • | 代表 OR 動作
  • - 代表 NOT 否定
  • " 包起來的字串代表要 phrase query
  • * 放在term之後代表 prefix query
  • ( and ) 表示優先度較高
  • ~N 放在字詞之後代表 edit distance (fuzziness)
  • ~N 放在 phrase 之後 代表 slop amount

不過上述的operators是可以透過參數 flags 來限制,預設此參數的值為 ALL,也就是這些 operators預設都支援

其實 default_operator 參數影響很大,舉個例子

GET /_search
{
  "query": {
    "simple_query_string": {
      "fields": [ "content" ],
      "query": "foo bar -baz"
    }
  }
}

原本的意圖是希望找出 content field 含有 foobar ,但是不含 baz
但因為 default_operatorOR
所以實際上解析出來是,搜尋 content field 含有 foobar 或 任何不含baz
也就是說 含有 baz 的documents也會被匹配得到,
那要怎麼達到原本意圖呢?
query string 改成 "foo bar +-baz" 即可,
代表著 欲搜尋 content field 含有 foobar "且" 不含baz

官方文件有說明到,此 simple_query_string query 比 query_string 還要 "穩健(robust)",
適合直接拿來對外給使用者使用

intervals query
對於 matching terms 的組合,可以做到很細微的排序以及位置接近程度的控制
是由 matching rules 組成,最後組成的rules套用在指定的 field

支援的rules有:

  • match
  • prefix
  • wildcard
  • fuzzy
  • all_of
  • any_of

match rule為例,提供了參數 max_gaps 控制匹配的terms之間可接受的最大的位置距離,
也提供了參數 ordered 設定匹配的terms的順序是否要和 query string中的位置順序一樣

intervals query 可以用到很精細微小,若有興趣深究可參考reference

common terms query
是個比較"專門"用來搜不常見的詞的query

不過因為在 es 7.3.0 被棄用了,且官方文件建議直接使用 match 所以在這就不多做介紹了


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


Reference

Full text queries
query string syntax
Intervals query


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

尚未有邦友留言

立即登入留言