自定義分析器
雖然Elasticsearch帶有一些現成的分析器,然而在分析器上Elasticsearch真正的強大之處在于,你可以通過在一個适合你的特定資料的設定之中組合字元過濾器、分詞器、詞彙單元過濾器來建立自定義的分析器。
一個 分析器 就是在一個包裡面組合了三種函數的一個包裝器, 三種函數按照順序被執行:
- 字元過濾器
- 字元過濾器 用來
一個尚未被分詞的字元串。例如,如果我們的文本是HTML格式的,它會包含像 整理
或者 <p>
這樣的HTML标簽,這些标簽是我們不想索引的。我們可以使用<div>
來移除掉所有的HTML标簽,并且像把 html_strip
轉換為相對應的Unicode字元 Á
Á
這樣,轉換HTML實體。
一個分析器可能有0個或者多個字元過濾器。
- 分詞器
- 一個分析器 必須 有一個唯一的分詞器。 分詞器把字元串分解成單個詞條或者詞彙單元。
标準
分析器裡使用的 标準 把一個字元串根據單詞邊界分解成單個詞條,并且移除掉大部分的标點符号,然而還有其他不同行為的分詞器存在。
例如, 關鍵詞 完整地輸出 接收到的同樣的字元串,并不做任何分詞。 空格 隻根據空格分割文本 。 正則 根據比對正規表達式來分割文本 。
- 詞單元過濾器
-
經過分詞,作為結果的 詞單元流 會按照指定的順序通過指定的詞單元過濾器 。
詞單元過濾器可以修改、添加或者移除詞單元。我們已經提到過 lowercase和 stop ,但是在 Elasticsearch 裡面還有很多可供選擇的詞單元過濾器。 詞幹過濾器 把單詞
為 詞幹。 ascii_folding移除變音符,把一個像 遏制
這樣的詞轉換為 "très"
。 ngram 和 edge_ngram 可以産生 适合用于部分比對或者自動補全的詞單元。"tres"
建立一個自定義分析器
和我們之前配置
es_std
分析器一樣,我們可以在
analysis
下的相應位置設定字元過濾器、分詞器和詞單元過濾器:
PUT /my_index{
"settings": {
"analysis": {
"char_filter": { ... custom character filters ... },
"tokenizer": { ... custom tokenizers ... },
"filter": { ... custom token filters ... },
"analyzer": { ... custom analyzers ... }
}
}}
作為示範,讓我們一起來建立一個自定義分析器吧,這個分析器可以做到下面的這些事:
- 使用
字元過濾器移除HTML部分。html清除
- 使用一個自定義的
字元過濾器把 映射
替換為 &
:" and "
- 使用
分詞器分詞。标準
- 小寫詞條,使用
詞過濾器處理。小寫
- 使用自定義
詞過濾器移除自定義的停止詞清單中包含的詞:停止
彙總起來,完整的
建立索引
請求 看起來應該像這樣:
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"
}
}
}