iT邦幫忙

2024 iThome 鐵人賽

DAY 0
0
自我挑戰組

重新開始 elasticsearch 系列 第 7

2024 鐵人賽 Day8: Text Analyzer III

  • 分享至 

  • xImage
  •  

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

除了在資料寫入(建立索引) ES 時會使用 Analyzer,在全文搜尋的時候也會用到,搜尋的時候預設會使用跟被搜索的 Index 中同樣的 Analyzer,但可以自訂搜尋時要使用的 Analyzer;這兩個階段使用的 Analyzer 就分別稱為 Index analyzer 和 search analyzer。

以下是一個簡單的例子:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        **<index_analyzer>,**
				**<search_analyzer>**
      },
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": **<index_analyzer>**,
        "search_analyzer": **<search_analyzer>**
      }
    }
  }
}

分開 Index Analyzer 和 Search Analyzer 提供了彈性多樣的搭配選擇,可以透過設計想辦法符合各種不同的搜尋情境,在加之 ES 提供各種不同的 Search function,讓 ES 有一種實驗的有趣性質。

而這也是 auto complete 實作的的重點之一,ES 有一個內建的 tokenizer — edge ngram tokenizer,利用這個 tokenizer 當作 index analyzer,一般的 tokenizer 當作 search analyzer ,就可以實現 search as you type 的功能。

接下來做個簡單的實作來展現 search analyzer 和 index analyzer 的使用。

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        **"edge_ngram_2to10": {
          "tokenizer": "edge_ngram_2to10",
          "filter": [
            "lowercase"
          ]
        },
        "search_as_type": {
          "tokenizer": "lowercase"
        }
      },
      "tokenizer": {
        "edge_ngram_2to10": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter"
          ]
        }
      }**
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "**edge_ngram_2to10**",
        "search_analyzer": "**search_as_type**"
      }
    }
  }
}
  • index settings/analysis 中定義了兩個 Analyzer,一個是 edge_ngram_2to10,另外一個是 search_as_type
  • edge_ngram_2to10 analyzer 組合了同名的 tokenizer 和 lowercase filter,同名的 tokenizer 設定產生最小長度為 2、最大長度為 10 的文字片段作為 index 的 token。
  • type_as_search analyzer 中只有 lowercase tokenizer。
  • 在 index mapping 中,title 這個欄位在 index 的時候會使用 edge_ngram_2to10 analyzer ,也就是把 title 這個 field 內的文字以 edge ngram 的方式索引、在 search 的時候,使用 search_as_type 只將 search query 的文字用空白切分後轉為小寫的。

接下來 ingest 3 個文本:


PUT my-index-000001/_doc/1
{
  "title": "Quick Foxes" 
}

PUT my-index-000001/_doc/2
{
  "title": "Quick Ford" 
}

PUT my-index-000001/_doc/3
{
  "title": "Quick Fool" 
}

在 console 上沒有辦法模擬搜尋列,每次輸入有變更就重新送出 request,但可以手動試試使用以下的 query 多打一個字就送出一次,應該會是 search as you type 的效果。


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

這幾篇文章大致說明了 ES 的基本知識與建立文本索引的概念,接下來會說明 search query 的部分。


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

尚未有邦友留言

立即登入留言