沉淀再出发: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的强大功能,以及如何使用插件扩展的方法,为咱们之后自建搜索引擎提供了工具。

相关文章
相关标签/搜索