elasticsearch實戰---中文拼音A-Z排序(完美解決)
公司目前業務系統偏向後臺系統,目前包含500W+資料,在許多列表中支援各種條件查詢,含有大量的模糊搜尋條件。由於在mysql中模糊查詢效率低下,目前公司已使用es搜尋引擎進行條件搜尋。es版本如下:
elasticsearch版本:6.3.2
java client版本:rest-high-level-client 6.3.2
問題:業務需要部分中文欄位進行a-z拼音排序。
1.實現方案
網上查閱資料,es使用 elasticsearch-analysis-pinyin 分詞外掛可實現排序效果。具體原理是通過拼音分詞器將漢字分為只含有首字母的字串(例如:劉德華----> ldh),之後通過查詢此分詞欄位實現排序。
2.說幹就幹
2.1下載、安裝拼音分詞器
elasticsearch-analysis-pinyin下載網址: ofollow,noindex">github.com/medcl/elast…
根據自己的es版本下載對應的拼音分詞器版本,由於我的是6.3.2的版本,因此下載master版本的分詞器。

解壓zip包,命令列移動到解決後的包下,執行mvn 打包命令(沒有maven的自行下載):

mvn打包命令: mvn package

看到 BUILD SUCCESS
即為打包成功。
此時, target
目錄已經生成,進入 E:\Elasticsearch\elasticsearch-analysis-pinyin-master\target\releases
目錄下,解壓裡面的zip包,生成如下檔案:

將這三個檔案拷貝到es安裝目錄下的 plugins
目錄下的 pinyin
資料夾中(pinyin資料夾需要自己建立,可以任意命名):

重啟es,拼音分詞器到此安裝完成。
2.2索引setting、mapping設定
首先,建立索引時自定義索引setting:
由於我們需要將拼音分詞器和ik分詞器同時使用,因此在配置分析器時配置了兩個。
PUT /pinyinTestIndex { "index" : { "analysis" : { "analyzer" : { "default" : {//預設分詞器使用ik分詞器 "tokenizer" : "ik_max_word" }, "pinyin_analyzer" : {//自定義拼音分詞器 "tokenizer" : "my_pinyin" } }, "tokenizer" : { "my_pinyin" : {//拼音分詞器配置 "type" : "pinyin", "keep_first_letter":true, "keep_separate_first_letter" : false, "keep_full_pinyin" : false, "limit_first_letter_length" : 20, "lowercase" : true, "keep_none_chinese":false } } } } } 複製程式碼
在拼音分詞器配置中含有幾個配置,這些配置決定了能不能按照你的要求進行排序。 keep_first_letter
:包含首字母,例如:劉德華> ldh,default:true。
keep_separate_first_letter
:將字母分割,例如:劉德華> l,d,h,default:false。
keep_full_pinyin
:包含全拼拼音,例如:劉德華> [ liu,de,hua],default:true。
limit_first_letter_length
:設定first_letter結果的最大長度,default:16。
lowercase
:小寫非中文字母,default:true。
keep_none_chinese
: 不在結果中保留非中文字母或數字,default:true。
因此,我的拼音分詞器會有如下效果 -- 如果字串為劉德華,經過分詞後成為ldh,如果字串為劉德華A,經過分詞後成為ldha,如果字串為劉德華1,經過分詞後成為ldh1。此種分詞效果滿足我們的業務需求,當然還有其他的配置可選,來滿足不同的業務需求。
其他配置可參考elasticsearch-analysis-pinyin下載網址中的 README.md
選項進行選取。
之後,進行索引mapping檔案的建立,保證欄位使用拼音分詞器:
POST /pinyinTestIndex/dev/_mapping { "dev": { "properties": { "name": {//name欄位 "type": "text",//字串型別支援分詞 "analyzer": "pinyin_analyzer",//使用拼音分詞 "fields": {//包含的另一種不分詞效果 "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } 複製程式碼
到此,索引建立完畢。
2.3 使用java client排序查詢
//search api SearchSourceBuilder source = new SearchSourceBuilder(); //排序欄位SortOrder.ASC 升序SortOrder.DESC 降序 source.sort("name", SortOrder.ASC); //索引資訊 SearchRequest searchRequest = new SearchRequest("pinyinTestIndex"); searchRequest.types("dev"); searchRequest.source(source); //查詢 SearchResponse response =client.search(searchRequest); 複製程式碼