Elasticsearch Analyzer 內建分詞器

2022-11-04 15:00:52

Elasticsearch Analyzer 內建分詞器

篇主要介紹一下 Elasticsearch中 Analyzer 分詞器的構成 和一些Es中內建的分詞器 以及如何使用它們

前置知識

es 提供了 analyze api 可以方便我們快速的指定 某個分詞器 然後對輸入的text文字進行分詞 幫助我們學習和實驗分詞器

POST _analyze
{
  "analyzer": "standard",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog's, bone ]

1.Analyzer

在ES中有很重要的一個概念就是 分詞,ES的全文檢索也是基於分詞結合倒排索引做的。所以這一文我們來看下何謂之分詞。如何分詞。

分詞器是專門處理分詞的元件,在很多中介軟體設計中每個元件的職責都劃分的很清楚,單一職責原則,以後改的時候好擴充套件。
分詞器由三部分組成。

  • Character Filters : 主要對原文字做處理, 例如 去除 html 標籤
  • Tokenizer : 按照規則 把文字切分為單詞, 也就是分詞
  • Token Filters : 將切分後的單詞 進行加工處理, 小寫,刪除stopwords 停頓詞, 增加同義詞 , 擴充套件一些

分詞場景:

  1. 資料寫入index 的時候進行分詞
  2. query 查詢時候 需要對查詢文字 進行分詞

2.Elasticsearch 內建分詞器

在es中有不少內建分詞器

  • Standard Analyzer : 預設分詞器, 按Unicode文字分割演演算法拆分 , 轉化為小寫 , 支援中文(但是中文按照每個文字拆分,沒啥意義)
  • Simple Analyzer : 按照非字母切分 並且轉化為小寫
  • Stop Analyzer : 和 simple 一樣 但是多了 過濾停用詞(the a is) 預設使用 stop token filter 的 _ _ english _ _ 預定義
  • Whitespace Analyzer : 每當遇到 空格的時候 會進行分詞 , 不會轉小寫
  • Keyword Analyzer : 不分詞 直接將輸入當做輸出
  • Patter Analyzer : 正規表示式
  • Language : 語言分詞器 30多種
  • Customer Analyzer : 自定義分詞器

3. Standard Analyzer

Standard 是es中預設的分詞器 , 它是按照 Unicode 文字分割演演算法去 對文字進行分詞的

POST _analyze
{
  "analyzer": "standard",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog's, bone ]

3.1 Definition

包括了 轉小寫的 token filter 和 stop token filter 去除停頓詞

Tokenizer

  • [Standard Tokenizer]

Token Filters

  • [Standard Token Filter] : 沒用只是作為保留的token filter (The standard token filter currently does nothing. It remains as a placeholder in case some filtering function needs to be added in a future version.)
  • [Lower Case Token Filter] : 轉小寫的 token filter
  • [Stop Token Filter] : 停頓詞 token filter 預設是沒有開啟

3.2 Configuration

  • max_token_length : 最大的分詞長度,如果超過此長度 則直接分詞 default 255
  • stopwords : 預定義的停頓詞列表 如: _ _ englisth _ _ 或者 停頓詞陣列[] 預設 none 不設定
  • stopwords_path : 包含停頓詞的檔案路徑

3.3 實驗

// 使用 自定義的分詞器 基於 standard
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english_analyzer": {
          "type": "standard", 
          "max_token_length": 5, // 最大詞數
          "stopwords": "_english_" // 開啟過濾停頓詞 使用 englisth 語法
        }
      }
    }
  }
}


GET my_index/_analyze
{
  "analyzer": "my_english_analyzer",
  "text": "The hellogoodname jack"
}
// 可以看到 最長5個字元 就需要進行分詞了, 並且停頓詞 the 沒有了
["hello", "goodn", "ame", "jack"]

4. Simple Analyzer

簡單的分詞器 分詞規則就是 遇到 非字母的 就分詞, 並且轉化為小寫,(lowercase tokennizer )

POST _analyze
{
  "analyzer": "simple",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

[ the, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ]

4.1 Definition

Tokenizer

  • Lower Case Tokenizer

4.2 Configuation

無設定引數

4.3 實驗

simple analyzer 分詞器的實現 就是如下

PUT /simple_example
{
  "settings": {
    "analysis": {
      "analyzer": {
        "rebuilt_simple": {
          "tokenizer": "lowercase",
          "filter": [         
          ]
        }
      }
    }
  }
}

5. Stop Analyzer

stop analyzer 和 simple analyzer 一樣, 只是多了 過濾 stop word 的 token filter , 並且預設使用 english 停頓詞規則

POST _analyze
{
  "analyzer": "stop",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
// 可以看到 非字母進行分詞 並且轉小寫 然後 去除了停頓詞
[ quick, brown, foxes, jumped, over, lazy, dog, s, bone ]

5.1 Definition

Tokenizer

  • Lower Case Tokenizer : 轉小寫的

Token filters

  • Stop Token Filter : 過濾停頓詞 預設使用 規則 english

5.2 Configuration

  • stopwords : 指定分詞的規則 預設 english , 或者分詞的陣列
  • stopwords_path : 指定分詞停頓詞檔案

5.3 實驗

如下就是對 Stop Analyzer 的實現 , 先轉小寫 後進行停頓詞的過濾

PUT /stop_example
{
  "settings": {
    "analysis": {
      "filter": {
        "english_stop": {
          "type":       "stop",
          "stopwords":  "_english_" 
        }
      },
      "analyzer": {
        "rebuilt_stop": {
          "tokenizer": "lowercase",
          "filter": [
            "english_stop"          
          ]
        }
      }
    }
  }
}

設定 stopwords 引數 指定過濾的停頓詞列表

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_stop_analyzer": {
          "type": "stop",
          "stopwords": ["the", "over"]
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_stop_analyzer",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

[ quick, brown, foxes, jumped, lazy, dog, s, bone ]

6. Whitespace Analyzer

空格 分詞器, 顧名思義 遇到空格就進行分詞, 不會轉小寫

POST _analyze
{
  "analyzer": "whitespace",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

[ The, 2, QUICK, Brown-Foxes, jumped, over, the, lazy, dog's, bone. ]

6.1 Definition

Tokenizer

  • Whitespace Tokenizer

6.2 Configuration

無設定

6.3 實驗

whitespace analyzer 的實現就是如下, 可以根據實際情況進行 新增 filter

PUT /whitespace_example
{
  "settings": {
    "analysis": {
      "analyzer": {
        "rebuilt_whitespace": {
          "tokenizer": "whitespace",
          "filter": [         
          ]
        }
      }
    }
  }
}

7. Keyword Analyzer

很特殊 它不會進行分詞, 怎麼輸入 就怎麼輸出

POST _analyze
{
  "analyzer": "keyword",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

//注意 這裡並沒有進行分詞 而是原樣輸出
[ The 2 QUICK Brown-Foxes jumped over the lazy dog's bone. ]

7.1 Definition

Tokennizer

  • Keyword Tokenizer

7.2 Configuration

無設定

7.3 實驗

rebuit 如下 就是 Keyword Analyzer 實現

PUT /keyword_example
{
  "settings": {
    "analysis": {
      "analyzer": {
        "rebuilt_keyword": {
          "tokenizer": "keyword",
          "filter": [         
          ]
        }
      }
    }
  }
}

8. Patter Analyzer

正規表示式 進行拆分 ,注意 正則匹配的是 標記, 就是要被分詞的標記 預設是 按照 \w+ 正則分詞

POST _analyze
{
  "analyzer": "pattern",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
// 預設是 按照 \w+ 正則
[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ]

8.1 Definition

Tokennizer

  • Pattern Tokenizer

Token Filters

  • Lower Case Token Filter
  • Stop Token Filter (預設未開啟)

8.2 Configuration

pattern A Java regular expression, defaults to \W+.
flags Java regular expression.
lowercase 轉小寫 預設開啟 true.
stopwords 停頓詞過濾 預設none 未開啟 , Defaults to _none_.
stopwords_path 停頓詞檔案路徑

8.3 實驗

Pattern Analyzer 的實現 就是如下

PUT /pattern_example
{
  "settings": {
    "analysis": {
      "tokenizer": {
        "split_on_non_word": {
          "type":       "pattern",
          "pattern":    "\\W+" 
        }
      },
      "analyzer": {
        "rebuilt_pattern": {
          "tokenizer": "split_on_non_word",
          "filter": [
            "lowercase"       
          ]
        }
      }
    }
  }
}

9. Language Analyzer

提供瞭如下 這麼多語言分詞器 , 其中 english 也在其中

arabic, armenian, basque, bengali, bulgarian, catalan, czech, dutch, english, finnish, french, galician, german, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian, portuguese, romanian, russian, sorani, spanish, swedish, turkish.

GET _analyze
{
  "analyzer": "english",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
[ 2, quick, brown, foxes, jumped, over, lazy, dog, bone ]

10. Customer Analyzer

沒啥好說的 就是當提供的 內建分詞器不滿足你的需求的時候 ,你可以結合 如下3部分

  • Character Filters : 主要對原文字做處理, 例如 去除 html 標籤
  • Tokenizer : 按照規則 把文字切分為單詞, 也就是分詞
  • Token Filters : 將切分後的單詞 進行加工處理, 小寫,刪除stopwords 停頓詞, 增加同義詞 , 擴充套件一些
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "type": "custom",
          "char_filter": [
            "emoticons" 
          ],
          "tokenizer": "punctuation", 
          "filter": [
            "lowercase",
            "english_stop" 
          ]
        }
      },
      "tokenizer": {
        "punctuation": { 
          "type": "pattern",
          "pattern": "[ .,!?]"
        }
      },
      "char_filter": {
        "emoticons": { 
          "type": "mapping",
          "mappings": [
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      "filter": {
        "english_stop": { 
          "type": "stop",
          "stopwords": "_english_"
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text":     "I'm a :) person, and you?"
}

[ i'm, _happy_, person, you ]

總結

本篇主要介紹了 Elasticsearch 中 的一些 內建的 Analyzer 分詞器, 這些內建分詞器可能不會常用,但是如果你能好好梳理一下這些內建 分詞器,一定會對你理解Analyzer 有很大的幫助, 可以幫助你理解 Character Filters , Tokenizer 和 Token Filters 的用處.

有機會再聊聊 一些中文分詞器 如 IKAnalyzer, ICU Analyzer ,Thulac 等等.. 畢竟開發中 中文分詞器用到更多些

歡迎大家存取 個人部落格 Johnny小屋
歡迎關注個人公眾號