您现在的位置是: 首页 > Elasticsearch IK分词插件


Elasticsearch IK分词插件

纯真年代 2019-06-06 16:31:11 0 389人围观

    以下基于ES6.4.3 ,analyzer在ES的搜索命中率当中起着重要的作用,其默认的analyzer为Standard Analyzer 

Elasticsearch添加中文分词

参考直达车:https://github.com/medcl/elasticsearch-analysis-ik ,请注意版本对应

ik有两种分词器:

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

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

IK安装

安装的方式有几种,这里使用elasticsearch-plugin安装

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.3/elasticsearch-analysis-ik-6.4.3.zip
IK分词效果

测试ik_max_word  http://192.168.31.100:9200/_analyze?pretty

{
"text": "中华人民共和国国歌",
"analyzer": "ik_max_word"
}

响应

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


测试ik_smart   http://192.168.31.100:9200/_analyze?pretty

{
"text": "中华人民共和国国歌",
"analyzer": "ik_smart"
}

响应

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

创建测试索引 PUT http://192.168.31.100:9200/ik_test?pretty

{
"mappings": {
"_doc": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}

插入数据  http://192.168.31.100:9200/ik_test/_doc/_bulk?pretty  ,注意最后有一个换行

{ "index" : { "_id" : "1" } }
{"content":"美国留给伊拉克的是个烂摊子吗"}
{ "index" : { "_id" : "2" } }
{"content":"公安部:各地校车将享最高路权"}
{ "index" : { "_id" : "3" } }
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}
{ "index" : { "_id" : "4" } }
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}

查询  http://192.168.31.100:9200/ik_test/_doc/_search?pretty

{
"query" : { "match" : { "content" : "中国" }},
"highlight" : {
"pre_tags" : ["<tag1>", "<tag2>"],
"post_tags" : ["</tag1>", "</tag2>"],
"fields" : {
"content" : {}
}
}
}

响应

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

我们可以在config/analysis-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>

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

  1. 该 http 请求需要返回两个头部(header),一个是 Last-Modified,一个是 ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。

  2. 该 http 请求返回的内容格式是一行一个分词,换行符用 \n 即可。

热更新 IK 分词使用方法

首先测试一下,比如蔡徐坤三个字,我们直接测试如下,发现蔡徐坤不是我们的字典热词,每个字都被拆分了



但是由于蔡徐坤上了热搜,我们一般不把它拆分,怎么办呢,这里我们将蔡徐坤作为我们的字典,这样就可以避免拆分了。

这里我们使用远程字典配置,这里可以直接使用https://www.bblog.vip/ik_test,把其他三个都注释了

<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">https://www.bblog.vip/ik_test</entry>

效果如下:




全部评论