前一篇說到 ES 會對 type 是 text 的 field 進行文字分析後供全文檢索,在說明『文字分析』確切是什麼之前,要先解釋一下 inverted index(倒排索引)這個概念;當初我在學 ES 的時候,是從『使用』開始的,在使用上遇到了很多跟我想像不一樣的結果,在理解 inverted index 後,覺得打通了很多不理解的部分,如果你希望可以跟 ES 相處順利,這個概念不要跳過喔~
想像一下在電腦普及之前的倉庫裡,放眼望去有無止盡的貨架,貨架上有諸多種類的產品放在比貨品大很多的的紙箱中,今天因為公司規定的更改,任何含有『酒精』成分的產品需要被搬移到另外的倉庫,目前管理的文件中對於倉儲物品的紀錄是表格化的,寫著以貨品為單位的資訊,成分那一欄是隨意長度的手寫文字;也就是很像這樣:
貨品名稱 | 倉儲位置 | 成分 | 大小 | 重量 | 分類 |
---|---|---|---|---|---|
玻璃水杯 | C4102 | 物品:矽、包裝:紙 | 12 * 4* 4.5 | 210g | 日用品 |
此時,如果有一個表格根據 {成分:物品清單}
這件事就會很快被解決了。
inverted index 就是這個 {成分: 物品清單}
的紀錄方法,將資料切分成元素,把元素當作 key 值,紀錄哪些資料包含這個元素,在透過元素找資料的時候就會相對快速。
在文本處理的領域,把文本(一串字)切成元素的步驟稱為分詞(tokenize),切出來的元素(通常是表意的詞)稱為 token。inverted index 套用在文本搜尋索引上就是把文本切成很多個 token 之後,拿 token 當 key,紀錄 token 出現在哪些文本裡。
以下為一個簡單的例子(內容是從 Elastic 官網隨機擷取的):
以下為三個文本
文本編號 1:retrieve selected fields from a search
文本編號 2:to retrieve specific fields in the search response
文本編號 3:use the fields parameter
針對三個文本進行 reverted index 的內容大概是這樣:
retrive: 1, 2
selected: 1
fields: 1, 2, 3
…(略)
paramater: 3
有了 inverted index,當文本增加到至成千上萬的時候,要知道哪個文本有 parmater 這個詞的時候就相當的容易了。
由此可以發現,怎麼把文本處理成要進行 reveted index 的 token 是會顯著影響搜尋的,例如根據上面的例子,如果搜尋『field』是會找不到東西的,因為只有『 fields』有被 index。
在文本資料處理中,除了 tokenize,還有很多其他的工程或是資料清理步驟讓資料變的更符合使用目的(目的不一定只是搜尋),例如定義停頓詞(stop-words)、同義詞、正規化(大小寫等同、複數型)等,也就是前述『文字分析』的部分。而這個部分 ES 會讓文本在被 index 前通過 Analyzer 來處理。
Analyzer 可以由三個成分組成,其中只有 tokenizer 是必要的:
這三個成分各自代表一種文字的處理,並且會依照上列的順序進行,也就是先以一個 document 為單位,進行文字的處理(character filter) → 分詞(tokenizer) → 以分詞為單位進行後處理(token filter)。
ES 根據不同的場景有內建幾個 Analyzer 可以直接使用,而組成內建 Analyzer 的這三個成分,你也可以自己來拿組合成自己的 Analyzer;當然如果要自己建造一個全新 Analyzer 的也沒有問題。
以下是一個簡單的例子,在 settins / analysis / analyzer 中定義了 my_customer_analyzer
,並於 description
這個 fields 使用 my_customer_analyzer
進行索引時的文字分析。
PUT my-index-000001
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "standard",
"char_filter": [
"html_strip"
],
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"properties": {
"description": {
"type": "text",
"analyzer": "my_custom_analyzer"
}
}
}
}
除了上面三項,Analyzer 還有以下兩個其他設定:
custom
表示為自訂的。match_phrase
query 中的 slop
參數使用。下一篇文章會說明如何設定自訂義(custom)的 Analyzer。