1搞挣、背景
一般情況下,有些搜索需求是需要根據(jù)拼音
和中文
來搜索的所坯,那么在elasticsearch
中是如何來實現(xiàn)基于拼音
來搜索的呢蒜绽?可以通過elasticsearch-analysis-pinyin
分析器來實現(xiàn)。
2、安裝拼音分詞器
# 進入 es 的插件目錄
cd /usr/local/es/elasticsearch-8.4.3/plugins
# 下載
wget https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v8.4.3/elasticsearch-analysis-pinyin-8.4.3.zip
# 新建目錄
mkdir analysis-pinyin
# 解壓
mv elasticsearch-analysis-pinyin-8.4.3.zip analysis-pinyin && cd analysis-pinyin && unzip elasticsearch-analysis-pinyin-8.4.3.zip && rm -rvf elasticsearch-analysis-pinyin-8.4.3.zip
cd ../ && chown -R es:es analysis-pinyin
# 啟動es
/usr/local/es/elasticsearch-8.4.3/bin/elasticsearch -d
3厉碟、拼音分詞器提供的功能
每個選項的含義
可以通過 文檔中的例子來看懂。
4屠缭、簡單測試一下拼音分詞器
4.1 dsl
GET _analyze
{
"text": ["我是中國人"],
"analyzer": "pinyin"
}
"analyzer": "pinyin"
此處的pinyin
是拼音分詞器自帶的箍鼓。
4.2 運行結果
從圖片上,實現(xiàn)了拼音分詞呵曹,但是這個不一定滿足我們的需求款咖,比如沒有中文了,單個的拼音(比如:wo)是沒有什么用的奄喂,需要對拼音分詞器進行定制化铐殃。
5、es中分詞器的組成
在elasticsearch
中分詞器analyzer
由如下三個部分組成:
-
character filters:
用于在tokenizer
之前對文本進行處理跨新。比如:
刪除字符富腊,替換字符等。 -
tokenizer:
將文本按照一定的規(guī)則分成獨立的token域帐。即實現(xiàn)分詞功能赘被。 -
tokenizer filter:
將tokenizer
輸出的詞條做進一步的處理。比如:
同義詞處理肖揣,大小寫轉換民假、移除停用詞,拼音處理等龙优。
6羊异、自定義一個分詞器實現(xiàn)拼音和中文的搜索
需求:
自定義一個分詞器,即可以實現(xiàn)拼音搜索彤断,也可以實現(xiàn)中文搜索野舶。
1、創(chuàng)建mapping
PUT /test_pinyin
{
"settings": {
// 分析階段的設置
"analysis": {
// 分析器設置
"analyzer": {
// 自定義分析器瓦糟,在tokenizer階段使用ik_max_word筒愚,在filter上使用py
"custom_analyzer": {
"tokenizer": "ik_max_word",
"filter": "custom_pinyin"
}
},
// 由于不滿足pinyin分詞器的默認設置,所以我們基于pinyin
// 自定義了一個filter菩浙,叫py巢掺,其中修改了一些設置
// 這些設置可以在pinyin分詞器官網(wǎng)找到
"filter": {
"custom_pinyin": {
"type": "pinyin",
// 不會這樣分:劉德華 > [liu, de, hua]
"keep_full_pinyin": false,
// 這樣分:劉德華 > [liudehua]
"keep_joined_full_pinyin": true,
// 保留原始token(即中文)
"keep_original": true,
// 設置first_letter結果的最大長度,默認值:16
"limit_first_letter_length": 16,
// 當啟用此選項時劲蜻,將刪除重復項以保存索引陆淀,例如:de的> de,默認值:false先嬉,注意:位置相關查詢可能受影響
"remove_duplicated_term": true,
// 如果非漢語字母是拼音轧苫,則將其拆分為單獨的拼音術語,默認值:true,如:liudehuaalibaba13zhuanghan- > liu含懊,de身冬,hua,a岔乔,li酥筝,ba,ba,13,zhuang冻押,han蜡镶,注意:keep_none_chinese和keep_none_chinese_together應首先啟用
"none_chinese_pinyin_tokenize": false
}
}
}
},
// 定義mapping
"mappings": {
"properties": {
"name": {
"type": "text",
// 創(chuàng)建倒排索引時使用的分詞器
"analyzer": "custom_analyzer",
// 搜索時使用的分詞器,搜索時不使用custom_analyzer是為了防止 詞語的拼音一樣,但是中文含義不一樣,導致搜索錯誤。 比如: 科技 和 客機步脓,拼音一樣,但是含義不一樣
"search_analyzer": "ik_smart"
}
}
}
}
注意:
可以看到 我們的 name
字段 使用的分詞器是 custom_analyzer
蝇更,這個是我們在上一步定義的沪编。但是搜索的時候使用的是 ik_smart
,這個為甚么會這樣呢年扩?
假設我們存在如下2個文本 科技強國
和 這是一架客機
蚁廓, 那么科技
和客機
的拼音是不是就是一樣的。 這個時候如果搜索時使用的分詞器也是custom_analyzer
那么厨幻,搜索科技
的時候客機
也會搜索出來相嵌,這樣是不對的。因此在搜索的時候中文就以中文搜况脆,拼音就以拼音搜饭宾。
{
"name": {
"type": "text",
"analyzer": "custom_analyzer",
"search_analyzer": "ik_smart"
}
}
當 analyzer
和search_analyzer
的值都是custom_analyzer
,搜索時也會通過拼音搜索格了,這樣的結果可能就不是我們想要的看铆。
2、插入數(shù)據(jù)
PUT /test_pinyin/_bulk
{"index":{"_id":1}}
{"name": "科技強國"}
{"index":{"_id":2}}
{"name": "這是一架客機"}
{"index":{"_id":3}}
3盛末、搜索數(shù)據(jù)
7弹惦、參考文檔
1、https://github.com/medcl/elasticsearch-analysis-pinyin/tree/master