在上一節中,我們給大家介紹了ES的分析器,我相信大家對ES的全文搜尋已經有了深刻的印象。分析器包含3個部分:字元過濾器、分詞器、分詞過濾器。在上一節的例子,大家發現了,都是英文的例子,是吧?因為ES是外國人寫的嘛,中國如果要在這方面趕上來,還是需要螢幕前的小夥伴們的~
英文呢,我們可以按照空格將一句話、一篇文章進行分詞,然後對分詞進行過濾,最後留下有意義的詞。但是中文怎麼分呢?中文的一句話是沒有空格的,這就要有一個強大的中文詞庫,當你的內容中出現這個詞時,就會將這個詞提煉出來。這裡大家也不用重複造輪子,經過前輩的努力,這個中文的分詞器已經有了,它就是今天要給大家介紹的IK中文分詞器。
IK中文分詞器的安裝
ES預設是沒有IK中文分詞器的,我們要將IK中文分詞器作為一個外掛安裝到ES中,安裝的步驟也很簡單:
-
從GitHub上下載適合自己ES版本的IK中文分詞器,地址如下:
https://github.com/medcl/elasticsearch-analysis-ik/releases
。 -
在我們的ES的外掛目錄中(
${ES_HOME}/plugins
)建立ik
目錄,mkdir ik
-
將我們下載好的IK分詞器解壓到
ik
目錄,這裡我們安裝unzip
命令,進行解壓。 -
重啟我們所有的ES服務。
到這裡,我們的IK中文分詞器就安裝完了。
IK中文分詞器初探
在上一節我們訪問了ES的分析器介面,指定了分析器和文字的內容,我們就可以看到分詞的結果。那麼既然我們已經安裝了Ik中文分詞器,當然要看一下效果了。在看效果之前,我們先要說一下,IK中文分詞器外掛給我們提供了兩個分析器。
- ik_max_word: 會將文字做最細粒度的拆分
- ik_smart:會做最粗粒度的拆分
我們先看看ik_max_word
的分析效果吧,
POST _analyze
{
"analyzer": "ik_max_word",
"text": "中華人民共和國國歌"
}
我們指定分詞器為ik_max_word
,文字內容為中華人民共和國國歌
。我們看一下分詞的結果:
{
"tokens": [
{
"token": "中華人民共和國",
"start_offset": 0,
"end_offset": 7,
"type": "CN_WORD",
"position": 0
},
{
"token": "中華人民",
"start_offset": 0,
"end_offset": 4,
"type": "CN_WORD",
"position": 1
},
{
"token": "中華",
"start_offset": 0,
"end_offset": 2,
"type": "CN_WORD",
"position": 2
},
{
"token": "華人",
"start_offset": 1,
"end_offset": 3,
"type": "CN_WORD",
"position": 3
},
{
"token": "人民共和國",
"start_offset": 2,
"end_offset": 7,
"type": "CN_WORD",
"position": 4
},
{
"token": "人民",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 5
},
{
"token": "共和國",
"start_offset": 4,
"end_offset": 7,
"type": "CN_WORD",
"position": 6
},
{
"token": "共和",
"start_offset": 4,
"end_offset": 6,
"type": "CN_WORD",
"position": 7
},
{
"token": "國",
"start_offset": 6,
"end_offset": 7,
"type": "CN_CHAR",
"position": 8
},
{
"token": "國歌",
"start_offset": 7,
"end_offset": 9,
"type": "CN_WORD",
"position": 9
}
]
}
我們可以看到,分詞分的非常細,我們在使用上面的這些進行搜尋時,都可以搜尋到中華人民共和國國歌
這個文字。我們再看一下另外一個分析器ik_smart
,
POST _analyze
{
"analyzer": "ik_smart",
"text": "中華人民共和國國歌"
}
我們的文字內容同樣是中華人民共和國國歌
,看一下分詞的效果,
{
"tokens": [
{
"token": "中華人民共和國",
"start_offset": 0,
"end_offset": 7,
"type": "CN_WORD",
"position": 0
},
{
"token": "國歌",
"start_offset": 7,
"end_offset": 9,
"type": "CN_WORD",
"position": 1
}
]
}
同樣的文字,使用ik_smart
進行分詞時,只分成了兩個詞,和ik_max_word
分詞器比少了很多。這就是兩個分詞器的區別,不過這兩個分析器都是可以對中文進行分詞的。
建立索引時指定IK分詞器
既然我們安裝了IK中文分詞器的外掛,那麼我們在建立索引時就可以為text
型別的欄位指定IK中文分詞器了。來看看下面的例子,
PUT ik_index
{
"mappings": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
我們建立了索引ik_index
,並且為欄位title
指定了分詞器ik_max_word
。我們執行一下,建立成功。然後我們再通過GET
請求看一下這個索引的對映情況。
GET ik_index/_mapping
返回的結果如下:
{
"ik_index": {
"mappings": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
我們可以看到title
欄位的分析器是ik_max_word
。
為索引指定預設IK分詞器
在上一節中,我們已經給大家介紹了為索引指定預設分詞器的方法,這裡我們直接把分詞器改為IK分詞器就可以了,如下:
PUT ik_index
{
"settings": {
"analysis": {
"analyzer": {
"default": {
"type": "ik_max_word"
}
}
}
}
}
這樣我們在索引中就不用建立每一個欄位,可以通過動態欄位對映,將String
型別的欄位對映為text
型別,同時分詞器指定為ik_max_word
。我們試一下,向ik_index
索引中新增一條記錄。
POST ik_index/_doc/1
{
"id": 1,
"title": "大興龐各莊的西瓜",
"desc": "大興龐各莊的西瓜真是好吃,脆沙瓤,甜掉牙"
}
執行成功。我們再執行搜尋試一下,如下:
POST ik_index/_search
{
"query": { "match": { "title": "西瓜" } }
}
我們搜尋title
欄位匹配西瓜
,執行結果如下:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "ik_index",
"_type": "_doc",
"_id": "1",
"_score": 0.2876821,
"_source": {
"id": 1,
"title": "大興龐各莊的西瓜",
"desc": "大興龐各莊的西瓜真是好吃,脆沙瓤,甜掉牙"
}
}
]
}
}
我們可以看到剛才插入的那條記錄已經搜尋出來了,看來我們的IK中文分詞器起作用了,而且搜尋的結果也符合我們的預期。我們再看看搜尋西
一個字的時候,能不能搜尋到結果,
POST ik_index/_search
{
"query": { "match": { "title": "西" } }
}
執行結果如下:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
並沒有搜尋出結果,說明在進行分詞時,西瓜
是作為一個詞出現的,並沒有拆分成每一個字,這也是符合我們預期的。
好了~ 這一節的IK中文分詞器就給大家介紹到這裡了~~