ElasticSearch-IK分詞器和整合使用
阿新 • • 發佈:2021-01-26
## 1.查詢存在問題分析
在進行字串查詢時,我們發現去搜索"搜尋伺服器"和"鋼索"都可以搜尋到資料;
而在進行詞條查詢時,我們搜尋"搜尋"卻沒有搜尋到資料;
究其原因是ElasticSearch的標準分詞器導致的,當我們建立索引時,欄位使用的是標準分詞器:
>如果使用ES搜尋中文內容,預設是不支援中文分詞,英文支援
>
>例如:How are you!
>
>How
>
>are
>
>you
>
>!
>
>例如:我是一個好男人!
>
>我
>
>是
>
>一
>
>個
>
>好
>
>男
>
>人
>
>!
```json
{
"mappings": {
"article": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":false
},
"title": {
"type": "text",
"store": true,
"index":true,
"analyzer":"standard" //標準分詞器 standard 內建的不支援中文分詞
},
"content": {
"type": "text",
"store": true,
"index":true,
"analyzer":"standard" //標準分詞器
}
}
}
}
}
```
例如對 "我是程式設計師" 進行分詞
標準分詞器分詞效果測試:
```http
GET http://localhost:9200/_analyze
```
```json
{ "analyzer": "standard", "text": "我是程式設計師" }
```
分詞結果:
```json
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "",
"position" : 1
},
{
"token" : "程",
"start_offset" : 2,
"end_offset" : 3,
"type" : "",
"position" : 2
},
{
"token" : "序",
"start_offset" : 3,
"end_offset" : 4,
"type" : "",
"position" : 3
},
{
"token" : "員",
"start_offset" : 4,
"end_offset" : 5,
"type" : "",
"position" : 4
}
]
}
```
而我們需要的分詞效果是:我、是、程式、程式設計師
這樣的話就需要對中文支援良好的分析器的支援,支援中文分詞的分詞器有很多,word分詞器、庖丁解牛、盤古分詞、Ansj分詞等,但我們常用的還是下面要介紹的IK分詞器。
## 2.IK分詞器簡介
IKAnalyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包。從2006年12月推出1.0版開始,IKAnalyzer已經推出 了3個大版本。最初,它是以開源專案Lucene為應用主體的,結合詞典分詞和文法分析演算法的中文分片語件。新版本的IKAnalyzer3.0則發展為 面向Java的公用分片語件,獨立於Lucene專案,同時提供了對Lucene的預設優化實現。
IK分詞器3.0的特性如下:
1)採用了特有的“正向迭代最細粒度切分演算法“,具有60萬字/秒的高速處理能力。
2)採用了多子處理器分析模式,支援:英文字母(IP地址、Email、URL)、數字(日期,常用中文數量詞,羅馬數字,科學計數法),中文詞彙(姓名、地名處理)等分詞處理。
3)對中英聯合支援不是很好,在這方面的處理比較麻煩.需再做一次查詢,同時是支援個人詞條的優化的詞典儲存,更小的記憶體佔用。
4)支援使用者詞典擴充套件定義。
5)針對Lucene全文檢索優化的查詢分析器IKQueryParser;採用歧義分析演算法優化查詢關鍵字的搜尋排列組合,能極大的提高Lucene檢索的命中率。
## 3. IK分詞器的安裝
1)下載地址:[https://github.com/medcl/elasticsearch-analysis-ik/releases](https://github.com/medcl/elasticsearch-analysis-ik/releases)
課程資料也提供了IK分詞器的壓縮包:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191129112646441.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JydWNlTGl1X2NvZGU=,size_16,color_FFFFFF,t_70)2)解壓,將解壓後的elasticsearch資料夾拷貝到elasticsearch-5.6.8\plugins下,並重命名資料夾為analysis-ik
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191129112937140.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JydWNlTGl1X2NvZGU=,size_16,color_FFFFFF,t_70)
3)重新啟動ElasticSearch,即可載入IK分詞器
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191129113140213.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JydWNlTGl1X2NvZGU=,size_16,color_FFFFFF,t_70)
## 4.IK分詞器測試
IK提供了兩個分詞演算法ik_smart 和 ik_max_word
其中 ik_smart 為最少切分,ik_max_word為最細粒度劃分
我們分別來試一下
1)最小切分:在瀏覽器位址列輸入地址
```http
GET http://localhost:9200/_analyze
```
```json
{ "analyzer": "ik_smart", "text": "我是程式設計師" }
```
輸出的結果為:
```json
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "程式設計師",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
}
]
}
```
2)最細切分:在瀏覽器位址列輸入地址
```http
http://127.0.0.1:9200/_analyze?analyzer=ik_max_word&pretty=true&text=我是程式設計師
```
輸出的結果為:
```json
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "程式設計師",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "程式",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "員",
"start_offset" : 4,
"end_offset" : 5,
"type" : "CN_CHAR",
"position" : 4
}
]
}
```
## 6. 修改索引對映mapping
### 6.1 重建索引
刪除原有blog1索引
```json
DELETE localhost:9200/blog1
```
建立blog1索引,此時分詞器使用ik_max_word
```json
PUT localhost:9200/blog1
```
```json
{
"mappings": {
"article": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":false
},
"title": {
"type": "text",
"store": true,
"index":true,
"analyzer":"ik_max_word"
},
"content": {
"type": "text",
"store": true,
"index":true,
"analyzer":"ik_max_word"
}
}
}
}
}
```
建立文件
```json
POST localhost:9200/blog1/article/1
```
```json
{
"id":1,
"title":"ElasticSearch是一個基於Lucene的搜尋伺服器",
"content":"它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放原始碼釋出,是當前流行的企業級搜尋引擎。設計用於雲端計算中,能夠達到實時搜尋,穩定,可靠,快速,安裝使用方便。"
}
```
### 6.2 再次測試queryString查詢
請求url:
```json
POST localhost:9200/blog1/article/_search
```
請求體:
```json
{
"query": {
"query_string": {
"default_field": "title",
"query": "搜尋伺服器"
}
}
}
```
postman截圖:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191129113604824.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JydWNlTGl1X2NvZGU=,size_16,color_FFFFFF,t_70)
將請求體搜尋字串修改為"鋼索",再次查詢:
```json
{
"query": {
"query_string": {
"default_field": "title",
"query": "鋼索"
}
}
}
```
postman截圖:![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191129113736255.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JydWNlTGl1X2NvZGU=,size_16,color_FFFFFF,t_70)
### 6.3 再次測試term測試
請求url:
```json
POST localhost:9200/blog1/article/_search
```
請求體:
```json
{
"query": {
"term": {
"title": "搜尋"
}
}
}
```
postman截圖:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191129113845413.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JydWNlTGl1X2NvZGU=,size_16,color_FFFF