Elasticsearch学习笔记--IK中文分词器

 

      如果直接使用Elasticsearch的朋友在处理中文内容的搜索时,肯定会遇到很尴尬的问题——中文词语被分成了一个一个的汉字,当用Kibana作图的时候,按照term来分组,结果一个汉字被分成了一组。

     这是因为使用了Elasticsearch中默认的标准分词器,这个分词器在处理中文的时候会把中文单词切分成一个一个的汉字,因此引入es之中文的分词器插件es-ik就能解决这个问题。

  具体参考可以查看:https://github.com/medcl/elasticsearch-analysis-ik

一 安装:

  • 第一步:下载es的IK插件 git clone https://github.com/medcl/elasticsearch-analysis-ik
  • 第二步:使用maven对下载的es-ik源码进行编译(mvn clean package -DskipTests)
  • 第三步:把编译后的target/releases下的elasticsearch-analysis-ik-1.10.3.zip文件拷贝到ES_HOME/plugins/ik目录下面,然后使用unzip命令解压如果unzip命令不存在,则安装:yum install -y unzip
  • 第四步:重启es服务
  • 第五步:测试分词效果: curl 'http://your ip:9200/zhouls/_analyze?analyzer=ik_max_word&pretty=true' -d '{"text":"这里是好记性不如烂笔头感叹号的博客们"}'

   注意:若你是单节点的es集群的话,则只需在一台部署es-ik。若比如像我这里的话,是3台,则需在三台都部署es-ik,且配置要一样。

二、IK使用

  IK有两种颗粒度的拆分:

ik_smart: 会做最粗粒度的拆分

ik_max_word: 会将文本做最细粒度的拆分

2.1、ik_smart 最粗粒度的拆分

测试:

GET _analyze?pretty
{
  "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
    }
  ]
}

2.2、ik_max_word 将文本做最细粒度的拆分

使用:

GET /index/_analyze?pretty
{
  "analyzer": "ik_max_word",
  "text": "中华人民共和国国歌"
}

得到结果:

{
  "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
    }
  ]

三、自定义词库

3.1 配置文件介绍

    IKAnalyzer.cfg.xml:用来配置自定义词库
    main.dic:        ik原生内置的中文词库,总共有27万多条,只要是这些单词,都会被分在一起
    quantifier.dic:放了一些单位相关的词
    suffix.dic:    放了一些后缀
    surname.dic:    中国的姓氏
    stopword.dic:    英文停用词

3.2 修改IKAnalyzer.cfg.xml

IKAnalyzer.cfg.xml:ext_dict配置项,custom/mydict.dic
  添加自定义停用词库
IKAnalyzer.cfg.xml:ext_stopwords配置项,custom/ext_stopword.dic




    IK Analyzer 扩展配置
    
    custom/mydict.dic;custom/single_word_low_freq.dic
    
    custom/ext_stopword.dic
    
    http://tagtic-slave01:82/HotWords.php
    
    
    http://tagtic-slave01:82/StopWords.php

四、热更新方案

  第一种:修改ik分词器源码,然后手动支持从mysql中每隔一定时间,自动加载新的词库
    ①下载源码
        https://github.com/medcl/elasticsearch-analysis-ik/tree/v6.2.4
    ②修改源码
        Dictionary类,169行:Dictionary单例类的初始化方法,在这里需要创建一个我们自定义的线程,并且启动它
        HotDictReloadThread类:就是死循环,不断调用Dictionary.getSingleton().reLoadMainDict(),去重新加载词典
        Dictionary类,389行:this.loadMySQLExtDict();
        Dictionary类,683行:this.loadMySQLStopwordDict();
    ③mvn package打包代码
        target\releases\elasticsearch-analysis-ik-6.2.4.zip
    ④解压缩ik压缩包
        将mysql驱动jar,放入ik的目录下
    ⑤将mysql驱动jar,放入ik的目录下
    ⑥修改jdbc相关配置
    ⑦重启es,观察日志
    ⑧在mysql中添加词库与停用词
    ⑨分词实验,验证热更新生效
    (点击下载已修改好的zip包)
第二种:基于ik分词器原生支持的热更新方案,部署一个web服务器,提供一个http接口,通过modified和tag两个http响应头,来提供词语的热更新

注:推荐用第一种。第二种ik git社区官方都不建议采用,觉得不太稳定。

 

 

你可能感兴趣的:(Elasticsearch)