ElasticSearch使用入門及拼音搜尋介紹
最近有個專案需要用到拼音搜尋並高亮顯示所匹配的中文,其實拼音搜尋可以通過將中文轉化為拼音儲存在庫表如mysql中,然後通過sql like語句查詢搜尋到對應的中文,在一些併發要求並不高、中文已知的情況下是完全可以做到拼音搜尋。但是由於專案要求不僅能夠搜尋出來對應的中文,但是對於高亮顯示匹配的中文難度成本就比較高了,此時需要通過中文拼音分詞來實現。
經過一番調研,鑑於elasticsearch社群的活躍,及相關拼音分詞外掛也比較豐富,選用ES作為搜尋方案。雖然現在ES版本已經到了6.x了,而且每隔一個月左右都會有新版本釋出,由於機器條件等的限制,ES版本越高越吃記憶體和CPU,所以選擇2.4.2版本,穩定、佔用記憶體小、支援叢集,滿足本次需求,如果空間不夠也可多安裝幾個ES組成叢集。
es安裝
官網選擇2.4.2的linux版本tgz安裝包下載上傳到linux伺服器,解壓後在bin中啟動,兩種啟動方式:
1.前臺啟動./elasticsearch
,啟動日誌顯示在前臺console,關閉會話則關閉ES
2.後臺啟動./elasticsearch -d
,啟動日誌列印在logs資料夾下。
此時可通過linux的curl
命令來請求ES的http restful介面建立索引、type、增刪改查等基本操作,也可通過Post等工具請求ES的Http介面。本文通過head工具進行操作。
安裝plugin-head
使用head外掛是ES必備的工具,除了可以操作請求restful介面操作ES資料庫,還可以用於觀察ES的狀態等。
通過在bin檔案下執行命令./plugin install mobz/elasticsearch-head
通過
ip:port/_plugin/head
即可訪問ES,port預設為9200,如果發現不能訪問,則需要在config檔案下的elasticsearch.yml
修改或新增如下網路配置,然後重啟es後再通過ip:port/_plugin/head
訪問即可(http.port
可配置)。 elasticsearch.yml配置,暫未知es的關閉方法,可通過
kill
命令關閉es
#網路及埠配置
network.host: 0.0.0.0
http.port: 11192
建立索引index
ES的Restful介面語法規則一般是用json
來進行資料儲存或設定,可通過head外掛中的【複合查詢】選單欄進行操作,支援多數HTTP傳輸模式。
ES中的索引相當於mysql的庫,type相當於mysql中的表。
ES建立索引的方式也很簡單,通過http PUT介面即可建立一個索引,如下:
http://172.168.1.11:11192/es_dev_v1
//通過對以上介面進行PUT操作,即可建立名為 es_dev_v1 的索引
建立完成後如下
建立type,並建立mapping
ES預設是可以不用設定type的mapping的,可以直接通過http儲存資料,ES會根據儲存的json資料自動建立一個type及對應的欄位mapping,如下
http://172.168.1.11:11192/es_dev_v1/temp/12
//傳輸方式:POST
{
"name":"test",
"address":"America",
"tel":"132134542"
}
//通過POST儲存資料,即在es_dev中的temp type(表)中儲存了一條id=12的資料,如果id不傳,則ES會自動建立一個id用於引用這條資料。
新增後的資料及mapping如下,3個欄位都預設為String型別
通過訪問http://172.168.1.11:11192/es_dev_v1
如何修改索引欄位型別(即mapping)
ES索引一旦建立,不支援修改索引的mapping,如修改某個欄位的型別、分詞、搜尋規則等,ES的規則是欄位型別只能是建立索引的時候就設定好或者由ES自動設定,如果要修改只能重新建立一個索引index,然後重新設定mapping.當然線上生產環境是不允許這麼做的。
可以借用別名來切換ES庫表,建立一個索引es_dev_v1
時,指定它的別名為es_dev
,當需要修改mapping時,再建立一個索引es_dev_v2
設定新的mapping,然後將資料刷入es_dev_v2
,刪除es_dev
與es_dev_v1
的別名關係,重新建立es_dev
和es_dev_v2
的關聯。此時使用es_dev
即可訪問索引庫。
參考:https://blog.csdn.net/lengfeng92/article/details/38230521
使用搜索
網上百度或部落格上對於Http或Java客戶端搜尋有很多的文章講解得很清楚,本文就不再贅述,再下節拼音搜尋會簡單搜尋。
中文拼音分詞工具使用
下載對應版本的拼音搜尋外掛,解壓copy至elasticsearch-2.4.2/plugins/pinyin
資料夾下面,其中包括elasticsearch-analysis-pinyin-1.8.2.jar
、nlp-lang-1.7.jar
、plugin-descriptor.properties
檔案,重啟es服務,如下圖
- 建立索引新增拼音分詞
給索引es_dev_v3新增拼音分析工具
http://172.168.1.11:11192/es_dev_v3 PUT
{
"index" : {
"analysis" : {
"analyzer" : {
"pinyin_analyzer" : {
"tokenizer" : "my_pinyin"
}
},
"tokenizer" : {
"my_pinyin" : {
"type" : "pinyin",
"keep_separate_first_letter" : false,
"keep_full_pinyin" : true,
"keep_original" : true,
"limit_first_letter_length" : 10,
"lowercase" : true,
"remove_duplicated_term" : true
}
}
}
}
}
- 測試分詞工具
訪問http://172.168.1.11:11192/es_dev_v3/_analyze?text=劉德華&analyzer=pinyin_analyzer
,返回拼音分詞結果如下,可看出elasticsearch-analysis-pinyin
支援拼音分詞和首字母縮寫
{
"tokens": [
{
"token": "liu",
"start_offset": 0,
"end_offset": 1,
"type": "word",
"position": 0
},
{
"token": "de",
"start_offset": 1,
"end_offset": 2,
"type": "word",
"position": 1
},
{
"token": "hua",
"start_offset": 2,
"end_offset": 3,
"type": "word",
"position": 2
},
{
"token": "劉德華",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 3
},
{
"token": "ldh",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 4
}
]
}
- 配置mapping
mapping新增如下設定,表示user
表中的userName欄位採用拼音分詞搜尋功能,而userPhone
欄位則不進行分詞。ES預設對所有String型別的欄位進行分詞,意味著搜尋是一個一個詞去匹配搜尋的,如果不需要分詞,則設定為not_analyzed
即可,此時則只支援精確匹配該欄位搜尋。
http://172.168.1.11:11192/es_dev_v3/user/_mapping POST
{
"user": {
"properties": {
"userName": {
"type": "string",
"fields": {
"pinyin": {
"type": "string",
"store": false,
"term_vector": "with_offsets",
"analyzer": "pinyin_analyzer",
"boost": 10
}
}
},
"userAddress": {
"type":"string",
"similarity": "classic"
},
"userPhone": {
"type":"string",
"index": "not_analyzed"
}
}
}
}
- 搜尋
以下均用match_phrase
短語搜尋匹配,其它搜尋如term
、match_all
等感興趣的同學可以在網上搜下其它技術部落格研究下。
1.通過POST介面上傳demo資料
2.userName
搜尋
POST請求介面 http://172.168.1.11:11192/es_dev_v3/user/_search
{
"query": {
"match_phrase": {
"userName": "張"
}
},
"highlight": {
"fields": {
"userName": {}
}
}
}
返回結果
{
"took": 126,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.19178301,
"hits": [
{
"_index": "es_dev_v3",
"_type": "user",
"_id": "1",
"_score": 0.19178301,
"_source": {
"userName": "張三",
"userAddress": "深圳南山",
"userPhone": "1387897454"
},
"highlight": {
"userName": [
"<em>張</em>三"
]
}
}
]
}
}
3.userName
拼音搜尋
POST請求 http://172.168.1.11:11192/es_dev_v3/user/_search
{
"query": {
"match_phrase": {
"userName.pinyin": "zhang"
}
},
"highlight": {
"fields": {
"userName.pinyin": {}
}
}
}
返回結果
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.5342641,
"hits": [
{
"_index": "es_dev_v3",
"_type": "user",
"_id": "1",
"_score": 1.5342641,
"_source": {
"userName": "張三",
"userAddress": "深圳南山",
"userPhone": "1387897454"
},
"highlight": {
"userName.pinyin": [
"<em>張</em>三"
]
}
}
]
}
}
- 如何修改index設定
http://172.168.1.11:11192/es_im_dev/_close POST 關閉索引
http://172.168.1.11:11192/es_im_dev/_settings PUT
{
"index": {
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "my_pinyin"
}
},
"tokenizer": {
"my_pinyin": {
"type": "pinyin",
"keep_separate_first_letter": true,
"keep_full_pinyin": true,
"keep_joined_full_pinyin": false,
"keep_original": true,
"limit_first_letter_length": 16,
"lowercase": true,
"remove_duplicated_term": true
}
}
}
}
}
http://172.168.1.11:11192/es_im_dev/_open POST 開啟索引
ES其它設定
- ES的記憶體設定
通過/elasticsearch-2.4.2/bin/elasticsearch.in.sh
檔案可修改ES的記憶體。
# check in case a user was using this mechanism
if [ "x$ES_CLASSPATH" != "x" ]; then
cat >&2 << EOF
Error: Don't modify the classpath with ES_CLASSPATH. Best is to add
additional elements via the plugin mechanism, or if code must really be
added to the main classpath, add jars to lib/ (unsupported).
EOF
exit 1
fi
ES_CLASSPATH="$ES_HOME/lib/elasticsearch-2.4.2.jar:$ES_HOME/lib/*"
# 記憶體大小設定
if [ "x$ES_MIN_MEM" = "x" ]; then
ES_MIN_MEM=256m
fi
if [ "x$ES_MAX_MEM" = "x" ]; then
ES_MAX_MEM=1g
fi
if [ "x$ES_HEAP_SIZE" != "x" ]; then
ES_MIN_MEM=$ES_HEAP_SIZE
ES_MAX_MEM=$ES_HEAP_SIZE
fi
# min and max heap sizes should be set to the same value to avoid
# stop-the-world GC pauses during resize, and so that we can lock the
# heap in memory on startup to prevent any of it from being swapped
- ES日誌設定
ES的日誌遵循log4j的設定模式,有多種型別可選擇。ES預設日誌是每天滾動記錄,預設型別(type)為dailyRollingFile
的方式,通過修改elasticsearch-2.4.2/config/logging.yml
檔案可設定日誌記錄方式為rollingFile
,並設定日誌記錄數量maxBackupIndex
及大小maxFileSize
即可有效減小日誌大小、防止吃滿硬碟。
appender:
console:
type: console
layout:
type: consolePattern
conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
file:
type: rollingFile
file: ${path.logs}/${cluster.name}.log
maxFileSize: 10000000
maxBackupIndex: 5
layout:
type: pattern
conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %.10000m%n"