Elasticsearch 分詞器

碼農充電站發表於2021-02-08

公號:碼農充電站pro
主頁:https://codeshellme.github.io

1,精確值與全文字

ES 中有精確值(Exact Values)與全文字(Full Text)之分:

  • 精確值:包括數字,日期,一個具體字串(例如"Hello World")。
    • 在 ES 中用 keyword 資料型別表示。
    • 精確值不需要做分詞處理。
  • 全文字:非結構化的文字資料。
    • 在 ES 中用 text 資料型別表示。
    • 全文字需要做分詞處理。

示例:

在這裡插入圖片描述

2,分詞過程

搜尋引擎需要建立單詞(Term / Token)與倒排索引項的對應關係,那麼首先就需要將文件拆分為單詞,這個過程叫做分詞

比如將 hello world 拆分為 helloworld,這就是分詞過程。

3,分詞器

ES 使用分詞器(Analyzer)對文件進行分詞,ES 中內建了很多分詞器供我們使用,我們也可以定製自己的分詞器。

一個分詞器有 3 個組成部分,分詞過程會依次經過這些部分

  1. Character Filters:字元過濾,用於刪去某些字元。該元件可以有 0 或多個。
  2. Tokenizer:分詞過程,按照某個規則將文件切分為單詞,比如用空格來切分。該元件有且只能有一個。
  3. Token Filter:對切分好的單詞進一步加工,比如大小寫轉換刪除停用詞等。該元件可以有 0 或多個。

4,ES 中的分詞器

ES 有下面這些內建的分詞器

  • Standard Analyzer:預設分詞器,按詞切分,轉小寫處理,也可以過濾停用詞(預設關閉)。
    • 在 ES 中的名稱為 standard
  • Simple Analyzer:按照非字母切分,非字母會被去除,轉小寫處理。
    • 在 ES 中的名稱為 simple
  • Stop Analyzer:按照非字母切分,非字母會被去除,轉小寫處理,停用詞過濾(the、a、is 等)。
    • 在 ES 中的名稱為 stop
  • Whitespace Analyzer:按照空格切分,不轉小寫。
    • 在 ES 中的名稱為 whitespace
  • Keyword Analyzer:不做任何的分詞處理,直接將輸入當作輸出。
    • 在 ES 中的名稱為 keyword
  • Pattern Analyzer:通過正規表示式進行分詞,預設為\W+非字元分隔,然後會進行轉小寫處理。
    • 在 ES 中的名稱為 pattern
  • Language Analyzers:提供了30多種常見語言的分詞器,比如:
    • english:英語分詞器,會對英文單詞進行歸一化處理,去掉停用詞等。
      • 歸一化處理:比如 running 變為 rungoods 變為 good 等。
    • 更多可參考這裡

5,測試分詞器

我們可以通過下面的 API 來測試分詞器

GET _analyze
{
  "analyzer": "AnalyzerName",
  "text": "內容"
}

6,自定義分詞器

當 ES 中的內建分詞器不能滿足需求時,我們可以定製自己的分詞器

在上文中已經介紹過一個分詞器由 3 部分組成:

  • Character Filters:字元過濾,用於刪去某些字元。
    • 該元件可以有 0 或多個。
  • Tokenizer:分詞過程,按照某個規則將文件切分為單詞,比如用空格來切分。
    • 該元件有且只能有一個。
  • Token Filter:對切分好的單詞進一步加工,比如大小寫轉換刪除停用詞等。
    • 該元件可以有 0 或多個。

6.1,內建分詞器元件

ES 對這 3 部分都有內建:

Character Filters 示例:

# 使用 html_strip
POST _analyze
{
  "tokenizer":"keyword",
  "char_filter":["html_strip"],
  "text": "<b>hello world</b>"
}

# 使用 mapping
POST _analyze
{
  "tokenizer": "standard",
  "char_filter": [
      {
        "type" : "mapping",
        "mappings" : [ "- => _"]
      }
    ],
  "text": "123-456, I-test! test-990 650-555-1234"
}

# 正則匹配替換
POST _analyze
{
  "tokenizer": "standard",
  "char_filter": [
      {
        "type" : "pattern_replace",
        "pattern" : "http://(.*)",
        "replacement" : "$1"
      }
    ],
    "text" : "http://www.elastic.co"
}

Tokenizer 示例:

POST _analyze
{
  "tokenizer":"path_hierarchy",
  "text":"/user/ymruan/a/b/c/d/e"
}

Token Filter 示例:

POST _analyze
{
  "tokenizer": "whitespace",
  "filter": ["stop"],
  "text": ["The gilrs in China are playing this game!"]
}

# 先 lowercase 再 stop
POST _analyze
{
  "tokenizer": "whitespace",
  "filter": ["lowercase","stop"],
  "text": ["The gilrs in China are playing this game!"]
}

6.2,自定義分詞器

自定義分詞器需要使用 settings 配置,示例:

PUT index_name
{
  "settings": {        # 固定寫法
    "analysis": {      # 固定寫法
      "analyzer": {    # 固定寫法
        "my_custom_analyzer": {     # 自定義分詞器的名稱
          "type": "custom",         # 固定寫法
          "tokenizer": "standard",  # 定義 tokenizer
          "char_filter": [          # 定義 char_filter
            "html_strip"
          ],
          "filter": [               # 定義 token filter
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  }
}

# 更復雜的一個示例
PUT index_name
{
  "settings": {         # 固定寫法
    "analysis": {       # 固定寫法
      "analyzer": {     # 固定寫法
        "my_custom_analyzer": {         # 自定義分詞器的名稱
          "type": "custom",             # 固定寫法
          "char_filter": [              # 定義 char_filter
            "emoticons"                 # 在下面定義
          ],
          "tokenizer": "punctuation",   # 定義 tokenizer
          "filter": [                   # 定義 token filter
            "lowercase",
            "english_stop"              # 在下面定義
          ]
        }
      },
      
      "tokenizer": {                   # 自定義 tokenizer
        "punctuation": {               # 自定義的 tokenizer 名稱
          "type": "pattern",           # type
          "pattern": "[ .,!?]"         # 分詞規則
        }
      },
      
      "char_filter": {                 # 自定義 char_filter
        "emoticons": {                 # 自定義的 char_filter 名稱
          "type": "mapping",           # type
          "mappings": [                # 規則
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      
      "filter": {                      # 自定義 token filter
        "english_stop": {              # 自定義 token filter 名稱
          "type": "stop",              # type
          "stopwords": "_english_"     
        }
      }
    }
  }
}

# 使用自定義分詞器
POST index_name/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "I'm a :) person, and you?"
}

7,安裝分詞器外掛

我們還可以通過安裝外掛的方式,來安裝其它分詞器。

比如安裝 analysis-icu 分詞器,它是一個不錯的中文分詞器:

elasticsearch-plugin install analysis-icu

analysis-icu 在 ES 中的名稱為 icu_analyzer

還有一些其它的中文分詞器:

安裝命令:

elasticsearch-plugin install analysis-ik
elasticsearch-plugin install analysis-hanlp
elasticsearch-plugin install analysis-pinyin

其它分詞器:

(本節完。)


推薦閱讀:

ElasticSearch 入門簡介

[ElasticSearch 安裝與執行](https://www.cnblogs.com/codeshell/p/14371473.html

Kibana,Logstash 和 Cerebro 的安裝執行

ElasticSearch 搜尋引擎概念簡介


歡迎關注作者公眾號,獲取更多技術乾貨。

碼農充電站pro

相關文章