ElasticSearch 中文分词器ik的安装、测试、使用、自定义词库、热更新词库


# 实验环境

  • 操作系统:Ubuntu 18.0.4
  • ElasticSearch版本:7.13.2
  • 中文分词分词器IK:elasticsearch-analysis-ik-7.13.2

# ik分词器的下载、安装、测试

## 安装方法一:使用elasticsearch-plugin 安装

该方法只支持v5.5.1 之后的版本:

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.13.2/elasticsearch-analysis-ik-7.13.2.zip

## 安装方法二:下载编译好的包进行安装

1、下载

下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
下载和ES相同版本的IK:
在这里插入图片描述

2、安装

因为elasticsearch-analysis-ik-7.13.2.zip是编译好的包,所以只需将elasticsearch-analysis-ik-7.13.2.zip解压到es的安装目录的/plugins/ik下面即可:

unzip -o elasticsearch-analysis-ik-7.13.2.zip -d /usr/share/elasticsearch/plugins/ik
3、重启ElasticSearch
查找es进程
ps -ef | grep elastic
杀掉es进程
kill -9 10713
重启es

进入es的安装目录的bin下,执行:

./elasticsearch -d

注意:如果遇到can not run elasticsearch as root报错,请查看这篇文章:
https://blog.csdn.net/willingtolove/article/details/118398026

4、测试
未使用ik分词器,使用默认分词器效果
POST 127.0.0.1:9200/_analyze
{
  "analyzer":"standard",
  "text":"中国人"
}

结果:

{
    "tokens": [
        {
            "token": "中",
            "start_offset": 0,
            "end_offset": 1,
            "type": "<IDEOGRAPHIC>",
            "position": 0
        },
        {
            "token": "国",
            "start_offset": 1,
            "end_offset": 2,
            "type": "<IDEOGRAPHIC>",
            "position": 1
        },
        {
            "token": "人",
            "start_offset": 2,
            "end_offset": 3,
            "type": "<IDEOGRAPHIC>",
            "position": 2
        }
    ]
}
使用IK分词器之后
POST 127.0.0.1:9200/_analyze
{
  "analyzer":"ik_max_word",
  "text":"中国人"
}

结果:

{
    "tokens": [
        {
            "token": "中国人",
            "start_offset": 0,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "中国",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 1
        },
        {
            "token": "国人",
            "start_offset": 1,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 2
        }
    ]
}

# ik分词器使用说明

## ik的分词模式

ik有两种分词模式:ik_smart , ik_max_word

  • ik_smart:会将文本做最粗粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、国歌」
  • ik_max_word:k_max_word:会将文本做最细粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、共和、国、国歌」,会穷尽各种可能的组合

## 创建索引时设置ik分词

创建users索引:

PUT 127.0.0.1:9200/users
{
    "settings": {
		"number_of_shards": 3,
		"number_of_replicas": 2
	},
    "mappings": {
        "properties": {
            "name": {
                "type": "text"
            },
            "age": {
                "type": "integer"
            },
            "describe": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_smart"
            }
        }
    }
}

从上面的例子中可以看到:

  • 索引usersdescribe字段的analyzer 属性设置为了ik_max_word,表示插入文档时,将describe字段按照ik_max_word做分词,然后插入倒排索引;
  • 索引usersdescribe字段的search_analyzer 属性设置为了ik_smart,表示在查询时,先对要查询的text类型的输入做按照ik_smart分词,再去倒排索引搜索;

# 自定义词库扩展

## 问题

有时候,我们搜索一些词库中没有的词,那应该是没有结果的;
比如:"达文西"这个text,想通过搜索"文西"搜索出来。
首先看下:"达文西"这个会被分成哪些词?

POST 127.0.0.1:9200/_analyze
{
  "analyzer":"ik_max_word",
  "text":"达文西"
}
{
    "tokens": [
        {
            "token": "达文西",
            "start_offset": 0,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 0
        }
    ]
}

从结果中可以看出,只能解析出一个词来,这样的话,搜索"文西"是搜索出来。

## 方法

通过自定义分词词典,来解决该问题。

1、首先进入es根目录中的plugins文件夹下的ik文件夹,进入config目录,创建mydic.dic文件

cd elasticsearch/plugins/ik/config
vi custom.dic

将自定义的词写进去:

达文
文西
2、打开IKAnalyzer.cfg.xml文件,将新建的mydic.dic配置其中
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">mydic.dic</entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

如果有多个自定义字典,可以这样配置:

<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">custom/mydict.dic;custom/mydict1.dic</entry>
3、重启ES

重启后测试:

POST 127.0.0.1:9200/_analyze
{
  "analyzer":"ik_max_word",
  "text":"达文西"
}
{
    "tokens": [
        {
            "token": "达文西",
            "start_offset": 0,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "达文",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 1
        },
        {
            "token": "文西",
            "start_offset": 1,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 2
        }
    ]
}

从结果中可以看到,"达文西"的被分词为:「达文西、达文、文西」三个词。说明自定义分词词典生效。

# 热更新 IK 分词

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

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

其中 location 是指一个 url,比如 http://yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。

http 请求需要返回两个头部(header),一个是 Last-Modified,一个是 ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。
该 http 请求返回的内容格式是一行一个分词,换行符用 \n 即可。
满足上面两点要求就可以实现热更新分词了,不需要重启 ES 实例。
es-ik 插件源码关于热更新的逻辑:
在这里插入图片描述

# 示例接口

        [HttpHead("HotUpdate"), HttpPost("HotUpdate"), HttpGet("HotUpdate")]
        public IActionResult GetHotUpdateDic()
        {
            Response.Headers.Add("Last-Modified", DateTime.Now.Ticks.ToString());
            Response.Headers.Add("ETag", DateTime.Now.Ticks.ToString());
            return Content("达尔\r\n尔文\r\n丽莎");
        }

# 测试

在没有配置热更新ik词库时:

POST 127.0.0.1:9200/_analyze
{
  "analyzer":"ik_max_word",
  "text":"娜丽莎"
}
{
    "tokens": [
        {
            "token": "娜丽莎",
            "start_offset": 0,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 0
        }
    ]
}

配置热更新ik分词词库:

	<!--用户可以在这里配置远程扩展字典 -->
	<entry key="remote_ext_dict">http://192.168.2.95:1660/api/fulltextsearch/HotUpdate</entry>
	<!--用户可以在这里配置远程扩展停止词字典-->
	<entry key="remote_ext_stopwords">http://192.168.2.95:1660/api/fulltextsearch/HotUpdateEnd</entry>

配置热更新ik分词词库一分钟后,测试:

POST 127.0.0.1:9200/_analyze
{
  "analyzer":"ik_max_word",
  "text":"娜丽莎"
}
{
    "tokens": [
        {
            "token": "娜丽莎",
            "start_offset": 0,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "丽莎",
            "start_offset": 1,
            "end_offset": 3,
            "type": "CN_WORD",
            "position": 1
        }
    ]
}

从测试结果中可以看出,「娜丽莎」的分词结果「娜丽莎、丽莎」,说明热更新已生效。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用 Elasticsearch 中的 IK 分词进行停词和自定义词的步骤: 1. 安装 ElasticsearchIK 分词插件。 2. 创建自定义词文件,格式如下: ``` # 单个词语 词语1 词语2 ... # 带有词性的词语 词语1,词性1 词语2,词性2 ... ``` 注:词性可以不写,用逗号隔开。 3. 将自定义词文件放置在 Elasticsearch 安装目录下的 `plugins/ik/config/` 目录下。 4. 修改 IK 分词配置文件,指定停用词文件和自定义词文件,示例如下: ``` { "index": { "analysis": { "analyzer": { "my_analyzer": { "type": "custom", "tokenizer": "ik_max_word", "filter": [ "my_stopwords", "my_synonyms" ] } }, "filter": { "my_stopwords": { "type": "stop", "stopwords_path": "stopwords.txt" }, "my_synonyms": { "type": "synonym", "synonyms_path": "synonyms.txt" } } } } } ``` 注:上面示例中使用了停用词文件和同义词文件,可以根据需要自行配置。 5. 创建索引并指定使用自定义分词。 ``` PUT /my_index { "settings": { "analysis": { "analyzer": { "my_analyzer": { "type": "custom", "tokenizer": "ik_max_word", "filter": [ "my_stopwords", "my_synonyms" ] } }, "filter": { "my_stopwords": { "type": "stop", "stopwords_path": "stopwords.txt" }, "my_synonyms": { "type": "synonym", "synonyms_path": "synonyms.txt" } } } }, "mappings": { "properties": { "my_field": { "type": "text", "analyzer": "my_analyzer" } } } } ``` 6. 测试分词效果。 可以使用以下命令测试分词效果: ``` GET /my_index/_analyze { "analyzer": "my_analyzer", "text": "自定义分词测试" } ``` 上述命令会返回分词结果,可以根据需要调整自定义词和停用词文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值