天天看點

elasticsearch中自定義分析器

自定義分析器

雖然Elasticsearch帶有一些現成的分析器,然而在分析器上Elasticsearch真正的強大之處在于,你可以通過在一個适合你的特定資料的設定之中組合字元過濾器、分詞器、詞彙單元過濾器來建立自定義的分析器。

一個 分析器 就是在一個包裡面組合了三種函數的一個包裝器, 三種函數按照順序被執行:

  • 字元過濾器
  • 字元過濾器 用來 ​

    ​整理​

    ​​ 一個尚未被分詞的字元串。例如,如果我們的文本是HTML格式的,它會包含像 ​

    ​<p>​

    ​​ 或者 ​

    ​<div>​

    ​​ 這樣的HTML标簽,這些标簽是我們不想索引的。我們可以使用​

    ​ html_strip ​

    ​​來移除掉所有的HTML标簽,并且像把 ​

    ​&Aacute;​

    ​​ 轉換為相對應的Unicode字元 ​

    ​Á​

    ​​ 這樣,轉換HTML實體。

    一個分析器可能有0個或者多個字元過濾器。

  • 分詞器
  • 一個分析器 必須 有一個唯一的分詞器。 分詞器把字元串分解成單個詞條或者詞彙單元。 ​

    ​标準​

    ​​ 分析器裡使用的 ​​标準​​​ 把一個字元串根據單詞邊界分解成單個詞條,并且移除掉大部分的标點符号,然而還有其他不同行為的分詞器存在。

    例如, ​​​關鍵詞​​​ 完整地輸出 接收到的同樣的字元串,并不做任何分詞。 ​​空格​​​ 隻根據空格分割文本 。 ​​正則​​ 根據比對正規表達式來分割文本 。

  • 詞單元過濾器
  • 經過分詞,作為結果的 詞單元流 會按照指定的順序通過指定的詞單元過濾器 。

    詞單元過濾器可以修改、添加或者移除詞單元。我們已經提到過 ​​​lowercase​​​和 ​​stop​​​ ,但是在 Elasticsearch 裡面還有很多可供選擇的詞單元過濾器。 ​​詞幹過濾器​​​ 把單詞 ​

    ​遏制​

    ​​ 為 詞幹。 ​​ascii_folding​​​移除變音符,把一個像 ​

    ​"très"​

    ​​ 這樣的詞轉換為 ​

    ​"tres"​

    ​​ 。 ​​ngram​​​ 和 ​​edge_ngram​​ 可以産生 适合用于部分比對或者自動補全的詞單元。

建立一個自定義分析器

和我們之前配置 ​

​es_std​

​​ 分析器一樣,我們可以在 ​

​analysis​

​ 下的相應位置設定字元過濾器、分詞器和詞單元過濾器:

PUT /my_index{
    "settings": {
        "analysis": {
            "char_filter": { ... custom character filters ... },
            "tokenizer":   { ...    custom tokenizers     ... },
            "filter":      { ...   custom token filters   ... },
            "analyzer":    { ...    custom analyzers      ... }
        }
    }}      

作為示範,讓我們一起來建立一個自定義分析器吧,這個分析器可以做到下面的這些事:

  1. 使用 ​

    ​html清除​

    ​ 字元過濾器移除HTML部分。
  2. 使用一個自定義的 ​

    ​映射​

    ​​ 字元過濾器把 ​

    ​&​

    ​​ 替換為 ​

    ​" and "​

    ​ :
  3. 使用 ​

    ​标準​

    ​ 分詞器分詞。
  4. 小寫詞條,使用 ​

    ​小寫​

    ​ 詞過濾器處理。
  5. 使用自定義 ​

    ​停止​

    ​​ 詞過濾器移除自定義的停止詞清單中包含的詞:

彙總起來,完整的 ​

​建立索引​

​ 請求 看起來應該像這樣:

PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": {
                "&_to_and": {
                    "type": "mapping",
                    "mappings": ["&=> and "]
                }
            },
            "filter": {
                "my_stopwords": {
                    "type": "stop",
                    "stopwords": ["the", "a"]
                }
            },
            "analyzer": {
                "my_analyzer": {
                    "type": "custom",
                    "char_filter": ["html_strip", "&_to_and"],
                    "tokenizer": "standard",
                    "filter": ["lowercase", "my_stopwords"]
                }
            }
        }
    }
}      

索引被建立以後,使用 ​

​analyze​

​ API 來 測試這個新的分析器:

POST / my_index / _analyze 

{

    "analyzer": "my_analyzer",

    "field": "name",

    "text": "text文本"

}

{
    "tokens": [{
            "token": "quick",
            "position": 2
        },
        {
            "token": "and",
            "position": 3
        },
        {
            "token": "brown",
            "position": 4
        },
        {
            "token": "fox",
            "position": 5
        }
    ]
}
 
這個分析器現在是沒有多大用處的,除非我們告訴 Elasticsearch在哪裡用上它。我們可以像下面這樣把這個分析器應用在一個 ​​string​​ 字段上:
 
PUT /my_index/_mapping
{
    "properties": {
        "title": {
            "type": "string",
            "analyzer": "my_analyzer"
        }
    }
}