一个 tokenizer(分词器)接收一个字符流,将之分割为独立的 tokens(词元,通常是独立的单词),然后输出 tokens 流。
例如 whitespace tokenizer
遇到空白字符时分割文本。它会将文本“Quick brown fox!
”分割为 [Quick,brown,fox!]
;
tokenizer(分词器)还负责记录各个 terms(词条) 的顺序或 position 位置(用于phrase短语和word proximity词近邻查询),以及 term(词条)所代表的原始word(单词)的 start(起始)和 end(结束)的 character offsets(字符串偏移量)(用于高亮显示搜索的内容)。
Elasticsearch
提供了很多内置的分词器,可以用来构建 custom analyzers(自定义分词器)。
POST _analyze
{
"analyzer": "whitespace",
"text": "The quick brown fox."
}
{
"tokens" : [
{
"token" : "The",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 0
},
{
"token" : "quick",
"start_offset" : 4,
"end_offset" : 9,
"type" : "word",
"position" : 1
},
{
"token" : "brown",
"start_offset" : 10,
"end_offset" : 15,
"type" : "word",
"position" : 2
},
{
"token" : "fox.",
"start_offset" : 16,
"end_offset" : 20,
"type" : "word",
"position" : 3
}
]
}
注意:所有的语言分词,默认使用的都是 “Standard Analyzer”,但是这些分词器针对于中文的分词,并不友好。为此需要安装中文的分词器。
IK 分词器就好解决了这个无问题,GitHub文档:https://github.com/medcl/elasticsearch-analysis-ik
K Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。
不能用默认 elasticsearch-plugin install xxx.zip 进行自动安装
必须到 https://github.com/medcl/elasticsearch-analysis-ik/releases/download 对应es版本然后手动安装
我的版本是7.4.2,所以我需要找到跟我一一对应的版本。
在前面安装的 elasticsearch 时,我们已经将 elasticsearch 容器的 /usr/share/elasticsearch/plugins
目录,映射到宿主机的 /mydata/elasticsearch/plugins
目录下,所以比较方便的做法就是下载 elasticsearch-analysis-ik-7.4.2.zip
文件,然后解压到该文件夹下即可。
安装完毕后,需要重启 elasticsearch 容器。
查看版本
curl http://localhost:9200
进入目录
cd /mydata/elasticsearch/plugins
下载压缩包
yum -y install wget
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
解压并删除压缩包,必须删除压缩包,否则会被当作插件导致 elasticsearch 启动失败
yum install -y unzip zip
unzip elasticsearch-analysis-ik-7.4.2.zip -d ik
rm -rf elasticsearch-analysis-ik-7.4.2.zip
重启容器
docker restart elasticsearch
测试使用
ik 分词器有两种常用的分词,分别是
ik_smart
和ik_max_word
ik_smart
POST _analyze
{
"analyzer": "ik_smart",
"text":"我是中国人"
}
// 结果
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "中国人",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
}
]
}
ik_max_word
POST _analyze
{
"analyzer": "ik_max_word",
"text":"我是乐心湖"
}
//结果
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "乐心",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "湖",
"start_offset" : 4,
"end_offset" : 5,
"type" : "CN_CHAR",
"position" : 3
}
]
}
从结果来看,它没有把“乐心湖”当做一个整体,这显然是不合理的,所以接下来我们肯定是要可以自定义词库了。
由于经常会有一些新的热点词或者流行词出现,自定义扩展词库是非常有必要的。例如 "乐心湖" 就是一个词。
在 ik 的配置文件夹 es/plugins/ik/config
中
我们可以在这里创建一个自定义词库文件 fenci.dic
,写入 乐心湖
,然后我们去编辑 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">./fenci.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">./fenci.dic</entry>
修改完配置文件后,需要重启 Elasticsearch。
POST _analyze
{
"analyzer": "ik_max_word",
"text": ["我是乐心湖"]
}
// 结果
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "乐心湖",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "乐心",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "湖",
"start_offset" : 4,
"end_offset" : 5,
"type" : "CN_CHAR",
"position" : 4
}
]
}
可以看到分词结果:“乐心湖”就单独成一个词了。
版权属于:乐心湖's Blog
本文链接:https://cloud.tencent.com/developer/article/1783066
声明:博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!