iT邦幫忙

2024 iThome 鐵人賽

DAY 0
1
自我挑戰組

重新開始 elasticsearch 系列 第 8

2024 鐵人賽 Day9: Search Query I

  • 分享至 

  • xImage
  •  

** 因為 elasticsearch 要打很多字,寫文苦手如我決定縮寫它,所以會用 ES 代稱。*

前面幾篇為了展示 Analyzer 的使用,已經使用過了 match 這個 query 來搜尋,這個 match query 是 full-text query 的語法。ES 除了 full-text query 之外,還有一些其他種類的 query:

  • term-level query
  • geo / spatial query
  • compound query

接下來會簡單介紹這幾種 query 的使用情境及一些簡單的範例。

Full-text query

目前在 ES 中,屬於 Full-text 的 query 有 9 個(官網文件),其中之前使用到的 match query 是進行全文搜尋時的標準 query,雖然已經出現很多次了,但還是解釋一下:

GET my-index-000001/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Quick For", 
      }
    }
  }
}

## syntax
# {
#  "query": {
#    "match": {
#      <field>: {
#        "query": <query string>, 
#      }
#    }
#  }
}

上面的 match 內的 fields 是想要搜尋的欄位,這個欄位如同前幾篇所述,在 index mapping 中需要指定為 text type 才能進行全文搜尋,還可以指定要索引的 analyzer 和搜尋的 analyzer(詳參前幾天文章);query 內則是放要搜尋的字詞。

然而除了指定要搜尋的欄位之外,還有很多其他可以設定的參數(全部的參數請參考官網說明),例如不想要用這個 field 定義的 Analyzer,也可以在 query 的時候以 anaylyzer 參數指定你要哪一個 analyzer;這邊想要說明一個很有用的搜尋方式:模糊搜尋(fuzzy search)。

模糊搜尋如字面所述,就是可以進行模糊的文字比對,通常使用在打錯字還是希望可以搜尋出相應資訊的情境,例如英文字 『fuzzy』 → 『fuzy』,中文字詞『球比賽』等。

然而要怎麼定義多模糊呢?通常使用的是 Levenshtein Edit Distance 這個計算方式,簡單的說是一個字跟他正確的拼法最少要置換(改、增、刪)多少個字,例如 fuzzy → fuzy 的模糊程度就是 1,因為只要在 z 跟 y 之間加上 z。

跟模糊搜尋主要的參數有兩個:

  • fuzziness:就是定義最大 Levenshtein Edit Distance,ES 預設的值是 auto ,也就是 ES 根據搜尋字 token 字長自己幫你定義模糊長度:
    • 字長 0~2 → 0,也就是不模糊搜尋
    • 字長 3~5 → 1
    • 字長 >5 → 2
  • prefix_length:在模糊搜尋中前綴詞的長度, 預設是 0,也就是沒有前綴詞。

接下來試試看:

# create index
PUT fuzzy_demo

# insert document
PUT fuzy_demo/_doc/1
{
  "title": "Elasticsearch Search Query" 
}

# search without fuzziness
GET fuzzy_demo/_search
{
  "query": {
    "match": {
      "title":{
        "query": "elasticseach"
      }
    }
  }
}

# get nothing

# search with fuzziness
GET fuzzy_demo/_search
{
  "query": {
    "match": {
      "title":{
        "query": "elasticseach",
        "fuzziness": "auto"
      }
    }
  }
}
# get the documents

# 試試看一個比較短的字
## 應該不會搜尋到,quri -> query 的 edit distacne 是 2
GET fuzzy_demo/_search
{
  "query": {
    "match": {
      "title":{
        "query": "quri",
        "fuzziness": "auto"
      }
    }
  }
}

## 應該會搜尋到,qury -> query 的 edit distacne 是 1
GET fuzzy_demo/_search
{
  "query": {
    "match": {
      "title":{
        "query": "qury",
        "fuzziness": "auto"
      }
    }
  }
}
  • 以上的結果都如我們預期,試試兩個單字的查詢,一個符合模糊搜尋,一個不符合。
GET fuzzy_demo/_search
{
  "query": {
    "match": {
      "title":{
        "query": "elasticseach quri",
        "fuzziness": "auto"
      }
    }
  }
}

結果還是比對到了,因為在多個 token 的情況,ES 預設任一符合即可;如果希望全部符合才算 match,可以加上 operator: and 設定如下。

GET fuzzy_demo/_search
{
  "query": {
    "match": {
      "title":{
        "query": "elasticseach quri",
        "fuzziness": "auto",
        "operator: "and"
      }
    }
  }
}

下一篇會繼續說明 search query 相關的內容。


上一篇
2024 鐵人賽 Day8: Text Analyzer III
下一篇
2024 鐵人賽 Day10: Search Query II
系列文
重新開始 elasticsearch 29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言