之前有介紹一個全文檢索程式 Meilisearch,不過目前還無法適用於中大型應用系統以及功能較少,而Elasticsearch 是目前最多人使用的全文檢索引擎,不只用於文字檢索還會用於地圖坐標運算及其他應用,並且能夠自己做多樣化的設定,而 Elasticsearch 本身並不支援中文,所以需要自行安裝分詞器,而現在多人在維護的分詞都是簡體中文的,本篇文章將教學如何安裝 Elasticsearch 並且支援繁體中文分詞
原始碼:https://github.com/elastic/elasticsearch
安裝 Elasticsearch
首先第一個步驟是安裝 Elasticsearch,這邊需要注意 Elasticsearch 要下載的版本
因為對應版本的外掛只能適用於對應版本的 Elasticsearch,為了方便 (省去自己手動編譯) 可以選擇有已經編譯好外掛的版本來安裝
舉例現在的 Elasticsearch 最新的是 8.3.3,但是目前 IK Analyzer 只有 8.2.3 那可以選擇下載 8.2.3 的 Elasticsearch
Elasticsearch 下載點連結:https://www.elastic.co/downloads/past-releases#elasticsearch
選擇下載對應作業系統的版本
下載後解壓縮後直接執行 binarry 就能啟動
./bin/elasticsearch
第一次啟動的時候會取得:
- 帳號密碼:用來登入的
- kibana 的 enrollment token:後面步驟用來給 kibana 連結認證用的
伺服器會啟動在:https://0.0.0.0:9200
安裝 kibana
kibana 下載連結:https://www.elastic.co/downloads/past-releases#kibana
選擇系統對應的版本與下載
下載後解壓縮直接執行 binarry 就能啟動
預設網頁會啟動在 http://localhost:5601
並且在第一次啟動會取得一個連結用來設定 elasticseach
將剛剛取得的 enrollment token 貼進去
稍微等一下就能進入登入畫面
輸入剛剛取得的帳號密碼就可以開始使用 kibana
安裝 IK 分析器
目前我們能找到有在維護的 Analyzer 分別都是簡體中文的,我們使用此簡體中文版本加一些設定來做到支援繁體中文
IK Analyzer 下載點:https://github.com/medcl/elasticsearch-analysis-ik/releases
下載後將解壓縮得到的資料夾放到 elasticsearch 中的 plugins 之中
重啟伺服器便完成安裝
可以進行測試一下,是否有支援簡體中文的文字
GET _analyze
{
"analyzer": "ik_smart",
"text": "传说中的厨具"
}
{
"tokens" : [
{
"token" : "传说中",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "的",
"start_offset" : 3,
"end_offset" : 4,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "厨具",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 2
}
]
}
設定支援繁體中文
支援繁體中文有兩個方式
方法一、直接修改 KL Analyzer 分詞內容,用工具轉成繁體中文並且加進分詞檔案
方法二、使用轉簡轉換 STConvert Analysis,先將輸入的繁體轉成簡體,再接 KL Analyzer 來分詞
方法一、直接修改 KL Analyzer 分詞內容
目前會分開的詞語是放在外掛資料夾中的 config/*.dic
使用文字編輯器開啟可以看到裡面有很多的詞語,使用工具將其轉換成繁體就可以了
這邊可以使用 opencc 轉換工具,下載點與安裝教學:https://github.com/BYVoid/OpenCC/wiki/Download
這樣使用指令將所有 dic 檔案內容補上繁體中文就可以:
opencc -c s2tw.json -i main.dic -o /tmp/main-zhtw.dic cp main.dic /tmp/main-zhcn.dic cat /tmp/main-zhtw.dic /tmp/main-zhcn.dic | sort | uniq > main.dic
重啟伺服器測試看看
GET _analyze
{
"analyzer": "ik_smart",
"text": "兼容異體字,可以實現動態替換"
}
{
"tokens" : [
{
"token" : "兼容",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "異體字",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "可以",
"start_offset" : 6,
"end_offset" : 8,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "實現",
"start_offset" : 8,
"end_offset" : 10,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "動態",
"start_offset" : 10,
"end_offset" : 12,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "替換",
"start_offset" : 12,
"end_offset" : 14,
"type" : "CN_WORD",
"position" : 5
}
]
}
方法二、使用轉簡轉換 STConvert Analysis
STConvert Analysis 下載點:https://github.com/medcl/elasticsearch-analysis-stconvert
下載後將解壓縮得到的資料夾放到 elasticsearch 中的 plugins 之中
重啟伺服器便完成安裝
接著要對指定的 index 進行設定「自定義分析器」
簡單來說分析器 (analysis) 是由 char_filter、tokenizer、filter 三個步驟來完成的,這邊設定是做到的步驟是:
step 1. 將文字轉成簡體
step 2. 使用 ik 分詞器將簡體中文語句進行分詞
step 3. 將分完的詞轉為繁體
PS: 詳細運作說明可以參考:https://www.elastic.co/guide/cn/elasticsearch/guide/current/custom-analyzers.html
PUT /product/_settings
{
"analysis": {
"char_filter": {
"stconvert": {
"type": "stconvert",
"delimiter": "#",
"keep_both": false,
"convert_type": "t2s"
}
},
"tokenizer": {
"ik_smart": {
"type": "ik_smart"
}
},
"filter": {
"stconvert": {
"type": "stconvert",
"delimiter": "#",
"keep_both": false,
"convert_type": "s2t"
}
},
"analyzer": {
"my_chinese_analyzer": {
"type": "custom",
"char_filter": ["stconvert"],
"tokenizer": "ik_smart",
"filter": ["stconvert"]
}
}
}
}
此時可以測試看看 ik 與 stconvert 一起運作的結果, 會取得簡體中文的分詞結果
GET product/_analyze
{
"analyzer" : "my_chinese_analyzer",
"text" : "傳說中的廚具"
}
{
"tokens" : [
{
"token" : "傳説中",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "的",
"start_offset" : 3,
"end_offset" : 4,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "廚具",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 2
}
]
}
接著就可以在指定的欄位使用要的分詞器
PUT /product/_mapping
{
"properties": {
"title": {
"type": "text",
"analyzer": "my_chinese_analyzer"
}
}
}
或是直接設定整個 index 全欄位使用相同分詞器
(將上面的自訂分詞器的 my_chinese_analyzer 直接改成 default)
POST /product/_close
PUT /product/_settings
{
"analysis": {
"char_filter": {
"stconvert": {
"type": "stconvert",
"delimiter": "#",
"keep_both": false,
"convert_type": "t2s"
}
},
"tokenizer": {
"ik_smart": {
"type": "ik_smart"
}
},
"filter": {
"stconvert": {
"type": "stconvert",
"delimiter": "#",
"keep_both": false,
"convert_type": "s2t"
}
},
"analyzer": {
"default": {
"type": "custom",
"char_filter": [
"stconvert"
],
"tokenizer": "ik_smart",
"filter": [
"stconvert"
]
}
}
}
}
POST /product/_open
















