1.查詢存在問題分析
在進行字串查詢時,我們發現去搜尋"搜尋伺服器"和"鋼索"都可以搜尋到資料;
而在進行詞條查詢時,我們搜尋"搜尋"卻沒有搜尋到資料;
究其原因是ElasticSearch的標準分詞器導致的,當我們建立索引時,欄位使用的是標準分詞器:
如果使用ES搜尋中文內容,預設是不支援中文分詞,英文支援
例如:How are you!
How
are
you
!
例如:我是一個好男人!
我
是
一
個
好
男
人
!
{
"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" //標準分詞器
}
}
}
}
}
例如對 "我是程式設計師" 進行分詞
標準分詞器分詞效果測試:
GET http://localhost:9200/_analyze
{ "analyzer": "standard", "text": "我是程式設計師" }
分詞結果:
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 1
},
{
"token" : "程",
"start_offset" : 2,
"end_offset" : 3,
"type" : "<IDEOGRAPHIC>",
"position" : 2
},
{
"token" : "序",
"start_offset" : 3,
"end_offset" : 4,
"type" : "<IDEOGRAPHIC>",
"position" : 3
},
{
"token" : "員",
"start_offset" : 4,
"end_offset" : 5,
"type" : "<IDEOGRAPHIC>",
"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
課程資料也提供了IK分詞器的壓縮包:
2)解壓,將解壓後的elasticsearch資料夾拷貝到elasticsearch-5.6.8\plugins下,並重新命名資料夾為analysis-ik
3)重新啟動ElasticSearch,即可載入IK分詞器
4.IK分詞器測試
IK提供了兩個分詞演算法ik_smart 和 ik_max_word
其中 ik_smart 為最少切分,ik_max_word為最細粒度劃分
我們分別來試一下
1)最小切分:在瀏覽器位址列輸入地址
GET http://localhost:9200/_analyze
{ "analyzer": "ik_smart", "text": "我是程式設計師" }
輸出的結果為:
{
"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://127.0.0.1:9200/_analyze?analyzer=ik_max_word&pretty=true&text=我是程式設計師
輸出的結果為:
{
"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索引
DELETE localhost:9200/blog1
建立blog1索引,此時分詞器使用ik_max_word
PUT localhost:9200/blog1
{
"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"
}
}
}
}
}
建立文件
POST localhost:9200/blog1/article/1
{
"id":1,
"title":"ElasticSearch是一個基於Lucene的搜尋伺服器",
"content":"它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放原始碼釋出,是當前流行的企業級搜尋引擎。設計用於雲端計算中,能夠達到實時搜尋,穩定,可靠,快速,安裝使用方便。"
}
6.2 再次測試queryString查詢
請求url:
POST localhost:9200/blog1/article/_search
請求體:
{
"query": {
"query_string": {
"default_field": "title",
"query": "搜尋伺服器"
}
}
}
postman截圖:
將請求體搜尋字串修改為"鋼索",再次查詢:
{
"query": {
"query_string": {
"default_field": "title",
"query": "鋼索"
}
}
}
postman截圖:
6.3 再次測試term測試
請求url:
POST localhost:9200/blog1/article/_search
請求體:
{
"query": {
"term": {
"title": "搜尋"
}
}
}
postman截圖: