天天看点

Elasticsearch之安装ik分词插件IK简介安装测试案例IK配置说明热更新 IK 分词使用方法

IK简介

IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词 歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。

IK Analyzer 2012特性:

- 采用了特有的“正向迭代最细粒度切分算法“,支持细粒度和智能分词两种切分模式;

- 在系统环境:Core2 i7 3.4G双核,4G内存,window 7 64位, Sun JDK 1.6_29 64位 普通pc环境测试,IK2012具有160万字/秒(3000KB/S)的高速处理能力。

- 2012版本的智能分词模式支持简单的分词排歧义处理和数量词合并输出。

- 采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,兼容韩文、日文字符

- 优化的词典存储,更小的内存占用。支持用户词典扩展定义。特别的,在2012版本,词典支持中文,英文,数字混合词语。

安装

  1. 编译打包
# 克隆远程库到本地
$ git clone https://github.com/medcl/elasticsearch-analysis-ik
$ cd elasticsearch-analysis-ik

# 查看tag列表
$ git tag

# 检出与elasticsearch版本相匹配的版本
$ git checkout tags/{version}

# 打包
$ mvn clean
$ mvn compile
$ mvn package
           
  1. 手动安装
# 解压到plugins/ik目录
$ unzip target/releases/elasticsearch-analysis-ik-{version}.zip ES_HOME/plugins/ik
           

注意:

- ES_HOME为ES对应安装目录

- version为选择的ik版本号

  1. 重启elasticsearch

备注:

- ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;

- ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。

测试案例

  1. 创建索引
curl -XPUT http://localhost:/index
           
  1. 创建mapping
curl -XPOST http://localhost:/index/fulltext/_mapping -d'
{
    "fulltext": {
             "_all": {
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word",
            "term_vector": "no",
            "store": "false"
        },
        "properties": {
            "content": {
                "type": "string",
                "store": "no",
                "term_vector": "with_positions_offsets",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word",
                "include_in_all": "true",
                "boost": 8
            }
        }
    }
}'
           
  1. 插入测试数据
curl -XPOST http://localhost:/index/fulltext/ -d'
{"content":"美国留给伊拉克的是个烂摊子吗"}
'
           
curl -XPOST http://localhost:/index/fulltext/ -d'
{"content":"公安部:各地校车将享最高路权"}
'
           
curl -XPOST http://localhost:/index/fulltext/ -d'
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}
'
           
curl -XPOST http://localhost:/index/fulltext/ -d'
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}
'
           
  1. 查询并高亮关键词
curl -XPOST http://localhost:/index/fulltext/_search  -d'
{
    "query" : { "term" : { "content" : "中国" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}
'
           

返回结果

{
    "took": ,
    "timed_out": false,
    "_shards": {
        "total": ,
        "successful": ,
        "failed": 
    },
    "hits": {
        "total": ,
        "max_score": ,
        "hits": [
            {
                "_index": "index",
                "_type": "fulltext",
                "_id": "4",
                "_score": ,
                "_source": {
                    "content": "中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
                },
                "highlight": {
                    "content": [
                        "<tag1>中国</tag1>驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首 "
                    ]
                }
            },
            {
                "_index": "index",
                "_type": "fulltext",
                "_id": "3",
                "_score": ,
                "_source": {
                    "content": "中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"
                },
                "highlight": {
                    "content": [
                        "均每天扣1艘<tag1>中国</tag1>渔船 "
                    ]
                }
            }
        ]
    }
}
           

IK配置说明

plugins/elasticsearch-analysis-ik-*/config/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">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
     <!--用户可以在这里配置自己的扩展停止词字典-->
    <entry key="ext_stopwords">custom/ext_stopword.dic</entry>
    <!--用户可以在这里配置远程扩展字典 -->
    <entry key="remote_ext_dict">location</entry>
    <!--用户可以在这里配置远程扩展停止词字典-->
    <entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry>
</properties>
           

热更新 IK 分词使用方法

目前该插件支持热更新 IK 分词,通过上文在 IK 配置文件中提到的如下配置

<!--用户可以在这里配置远程扩展字典 -->
    <entry key="remote_ext_dict">location</entry>
    <!--用户可以在这里配置远程扩展停止词字典-->
    <entry key="remote_ext_stopwords">location</entry>
           

其中

location

是指一个 url,比如

http://yoursite.com/getCustomDict

,该请求只需满足以下两点即可完成分词热更新。

  1. 该 http 请求需要返回两个头部(header),一个是

    Last-Modified

    ,一个是

    ETag

    ,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。
  2. 该 http 请求返回的内容格式是一行一个分词,换行符用

    \n

    即可。

满足上面两点要求就可以实现热更新分词了,不需要重启 ES 实例。

可以将需自动更新的热词放在一个 UTF-8 编码的 .txt 文件里,放在 nginx 或其他简易 http server 下,当 .txt 文件修改时,http server 会在客户端请求该文件时自动返回相应的 Last-Modified 和 ETag。可以另外做一个工具来从业务系统提取相关词汇,并更新这个 .txt 文件。

常见问题

  1. 自定义词典为什么没有生效?

    请确保你的扩展词典的文本格式为 UTF8 编码

  2. 设置elasticsearch默认分词为ik:在

    ES_HOME/config/elasticsearch.yml

    文件最后一行中增加

    index.analysis.analyzer.default.type: ik

    即可。
  3. 分词测试失败 请在某个索引下调用analyze接口测试,而不是直接调用analyze接口 如:http://localhost:9200/your_index/_analyze?text=中华人民共和国MN&tokenizer=my_ik

继续阅读