沉澱再出發:ElasticSearch的中文分詞器ik

沉澱再出發:ElasticSearch的中文分詞器ik

1、前言

  爲何要在elasticsearch中要使用ik這樣的中文分詞呢,那是由於es提供的分詞是英文分詞,對於中文的分詞就作的很是很差了,所以咱們須要一箇中文分詞器來用於搜索和使用。java

2、IK分詞器的安裝和使用

  2.一、安裝ik

   咱們能夠從官方github上下載該插件,咱們下載對應於咱們使用的es的版本的ik,而且咱們可以看到具體的安裝步驟,能夠有兩種安裝方法。git

     這裏咱們選擇第一種方式:github

 

   重啓es,咱們就可使用ik這個中文分詞器了。shell

   2.二、使用ik中文分詞器

   既然咱們要使用ik中文分詞器,那麼就必須先在index數據庫之中插入一些中文,而後再來索引一下這些中文的單詞,就能看出是否成功了。數據庫

   建立數據庫:json

使用kibana:    PUT /lsx_index
使用curl:      curl -XPUT http://localhost:9200/lsx_index

    使用ik建立映射:windows

curl -XPOST http://localhost:9200/lsx_index/zyr_fulltext/_mapping -H 'Content-Type:application/json' -d'
{
        "properties": {
            "content": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word"
            }
        }

}'

     若是使用kibana,那麼應該是:
app

 1 POST  /lsx_index/zyr_fulltext/_mapping
 2 {
 3         "properties": {
 4             "content": {
 5                 "type": "text",
 6                 "analyzer": "ik_max_word",
 7                 "search_analyzer": "ik_max_word"
 8             }
 9         }
10 }

   ElasticSearch 的分詞器稱爲analyzer。analyzer是字段文本的分詞器,search_analyzer是搜索詞的分詞器。ik_max_word分詞器是插件ik提供的,能夠對文本進行最大數量的分詞。ik_max_word: 會將文本作最細粒度的拆分,好比會將「中華人民共和國國歌」拆分爲「中華人民共和國,中華人民,中華,華人,人民共和國,人民,人,民,共和國,共和,和,國國,國歌」,會窮盡各類可能的組合;ik_smart: 會作最粗粒度的拆分,好比會將「中華人民共和國國歌」拆分爲「中華人民共和國,國歌」。curl

 

     插入一些數據(文檔):elasticsearch

   你們注意,咱們在插入數據的時候,若是使用git插入中文,則會出現以下錯誤,其實根本緣由是咱們使用的shell的字符集編碼的問題,所以咱們建議使用kibana來試一下:

{"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"failed to parse [content]"}],"type":"mapper_parsing_exception",
"reason":"failed to parse [content]","caused_by":{"type":"json_parse_exception","reason":"Invalid UTF-8 middle byte 0xc0\n at
[Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@29464944; line: 2, column: 15]
"}},"status":400}

      或者咱們下載curl的其餘curl工具,可是也是收效甚微:

    當咱們使用kibana的時候,一切都是那樣的天然:

PUT /lsx_index/zyr_fulltext/1?pretty
{
   "content":"這是一個測試文檔"
}

PUT /lsx_index/zyr_fulltext/2?pretty
{
   "content":"能夠了解一些測試方面的東西"
}

PUT /lsx_index/zyr_fulltext/3?pretty
{
   "content":"關於分詞方面的測試"
}
PUT /lsx_index/zyr_fulltext/4?pretty
{
   "content":"若是你想了解更多的內容"
}
PUT /lsx_index/zyr_fulltext/5?pretty
{
   "content":"能夠查看個人博客"
}
PUT /lsx_index/zyr_fulltext/6?pretty
{
   "content":"我是朱彥榮"
}

    下面咱們仍是分詞查詢:

POST /lsx_index/zyr_fulltext/_search { "query" : { "match" : { "content" : "關於分詞方面的測試,朱彥榮" } }, "highlight" : { "pre_tags" : ["<tag1>", "<tag2>"], "post_tags" : ["</tag1>", "</tag2>"], "fields" : { "content" : {} } } }

    結果以下:

{
  "took": 19,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 3.3319345,
    "hits": [
      {
        "_index": "lsx_index",
        "_type": "zyr_fulltext",
        "_id": "6",
        "_score": 3.3319345,
        "_source": {
          "content": "我是朱彥榮"
        },
        "highlight": {
          "content": [
            "我是<tag1>朱</tag1><tag1>彥</tag1><tag1>榮</tag1>"
          ]
        }
      },
      {
        "_index": "lsx_index",
        "_type": "zyr_fulltext",
        "_id": "2",
        "_score": 2.634553,
        "_source": {
          "content": "能夠了解一些測試方面的東西"
        },
        "highlight": {
          "content": [
            "能夠了解一些<tag1>測試</tag1><tag1>方面</tag1><tag1>的</tag1>東西"
          ]
        }
      },
      {
        "_index": "lsx_index",
        "_type": "zyr_fulltext",
        "_id": "3",
        "_score": 1.4384104,
        "_source": {
          "content": "關於分詞方面的測試"
        },
        "highlight": {
          "content": [
            "<tag1>關於</tag1><tag1>分詞</tag1><tag1>方面</tag1><tag1>的</tag1><tag1>測試</tag1>"
          ]
        }
      },
      {
        "_index": "lsx_index",
        "_type": "zyr_fulltext",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "content": "這是一個測試文檔"
        },
        "highlight": {
          "content": [
            "這是一個<tag1>測試</tag1>文檔"
          ]
        }
      }
    ]
  }
}
測試結果

    由此能夠看到分詞的強大功能了。

3、ik的高級配置

   3.一、ik的擴展配置

    若是咱們仔細查看插件的目錄,就能夠看到有不少的預先設定的配置,好比中止詞等等。

    咱們看一下IKAnalyzer.cfg.xml這個文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>IK Analyzer 擴展配置</comment>
    <!--用戶能夠在這裏配置本身的擴展字典 -->
    <entry key="ext_dict"></entry>
     <!--用戶能夠在這裏配置本身的擴展中止詞字典-->
    <entry key="ext_stopwords"></entry>
    <!--用戶能夠在這裏配置遠程擴展字典 -->
    <!-- <entry key="remote_ext_dict">words_location</entry> -->
    <!--用戶能夠在這裏配置遠程擴展中止詞字典-->
    <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

    擴展詞理所固然是咱們本身經常使用的,可是又不被普遍承認的詞,好比咱們的姓名等,下面是中止詞的一些理解:

    能夠看到咱們能夠增長一些配置在咱們的文件之中,好比咱們新建一個文件,這個文件之中加入咱們的分詞,而後從新啓動es,再次查詢這個詞,就能發現系統不會將這些詞分隔開了。這裏咱們須要注意,系統會默認將文件前面的目錄補全,咱們若是是在config目錄下面新建的文件詞典,那麼直接在配置之中寫入文件名便可。

  3.二、ik的擴展測試

    下面咱們從新創建一個索引,走一下這個過程,整個過程以下:

 1 #建立索引
 2 PUT /zyr_lsx_index
 3 
 4 #建立映射
 5 POST /zyr_lsx_index/zyr_lsx_fulltext/_mapping
 6 {
 7    "properties": {
 8        "detail_test": {
 9            "type": "text",
10            "analyzer": "ik_max_word",
11            "search_analyzer": "ik_max_word"
12         }
13    }
14 }
15 
16 #插入數據
17 PUT /zyr_lsx_index/zyr_lsx_fulltext/1?pretty
18 {
19    "detail_test":"這是一個測試文檔"
20 }
21 
22 PUT /zyr_lsx_index/zyr_lsx_fulltext/2?pretty
23 {
24    "detail_test":"能夠了解一些測試方面的東西"
25 }
26 
27 PUT /zyr_lsx_index/zyr_lsx_fulltext/3?pretty
28 {
29    "detail_test":"關於分詞方面的測試"
30 }
31 PUT /zyr_lsx_index/zyr_lsx_fulltext/4?pretty
32 {
33    "detail_test":"若是你想了解更多的內容"
34 }
35 PUT /zyr_lsx_index/zyr_lsx_fulltext/5?pretty
36 {
37    "detail_test":"能夠查看個人博客"
38 }
39 PUT /zyr_lsx_index/zyr_lsx_fulltext/6?pretty
40 {
41    "detail_test":"我是朱彥榮"
42 }
43 
44 
45 #搜索測試
46 POST /zyr_lsx_index/zyr_lsx_fulltext/_search
47 {
48     "query" : {
49       "match" : { "detail_test" : "朱彥榮" }
50     },
51     "highlight" : {
52         "pre_tags" : ["<tag1>", "<tag2>"],
53         "post_tags" : ["</tag1>", "</tag2>"],
54         "fields" : {
55             "detail_test" : {}
56         }
57     }
58 }

     同時咱們對ik的配置文件進行修改:

    IKAnalyzer.cfg.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
 3 <properties>
 4     <comment>IK Analyzer 擴展配置</comment>
 5     <!--用戶能夠在這裏配置本身的擴展字典 -->
 6     <entry key="ext_dict">zyr_test.dic</entry>
 7      <!--用戶能夠在這裏配置本身的擴展中止詞字典-->
 8     <entry key="ext_stopwords"></entry>
 9     <!--用戶能夠在這裏配置遠程擴展字典 -->
10     <!-- <entry key="remote_ext_dict">words_location</entry> -->
11     <!--用戶能夠在這裏配置遠程擴展中止詞字典-->
12     <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
13 </properties>

    重啓es,將上面的代碼執行一遍,而後就會發現,咱們本身定義的擴展詞已經生效了,不會再被分割成一個個的字了,至此,咱們對ik有了更深的理解,其次,咱們還能夠經過遠程的方式來更新咱們的詞庫,這樣,咱們就能理解搜狗輸入法的一些記憶功能了。

   其實咱們也能看到咱們的文件被加載了:

    最終的結果:

4、總結

      經過咱們對ik的學習,咱們更加深入的理解了es的強大功能,以及如何使用插件擴展的方法,爲咱們之後自建搜索引擎提供了工具。

相關文章
相關標籤/搜索