深入剖析elasticsearch自带中文分词问题及ik分词器的应用
elasticsearch自身具备的中文分词,是将中文逐个字拆开,完全没有词汇的概念。而在实际应用里,用户都是依据词汇来进行查询匹配的。要是能把文章按照词汇为单位切分,就能更精准地与用户查询条件匹配,查询速度也会更快。

GET _analyze
{
王婷很厉害,今日表现出色
}
#结果如下
{
"tokens" : [
{
"token" : "wang",
"start_offset" : 0,
"end_offset" : 4,
"type" : "",
"position" : 0
},
{
"token" : "ting",
"start_offset" : 5,
"end_offset" : 9,
"type" : "",
"position" : 1
},
{
"token" : "niubi",
"start_offset" : 10,
"end_offset" : 15,
"type" : "",
"position" : 2
},
{
"token" : "今",
"start_offset" : 16,
"end_offset" : 17,
"type" : "",
"position" : 3
},
{
"token" : "天",
"start_offset" : 17,
"end_offset" : 18,
"type" : "",
"position" : 4
},
{
"token" : "给",
"start_offset" : 18,
"end_offset" : 19,
"type" : "",
"position" : 5
},
{
"token" : "力",
"start_offset" : 19,
"end_offset" : 20,
"type" : "",
"position" : 6
}
]
}
从示例能够明显看出来,“wang ting niubi”,“今天给力” 英文分词按照空格分词比较合理 然而中文把一个个字拆开明显不合适 今天、给力两个词语未被识别
分词器下载网址:
# 进入es的plugins目录
aaa@ops01:/home 进入到 /opt/module/elasticsearch-6.6.0/plugins/ 目录下
该子目录在plugins下
在路径aaa@ops01:/opt/module/elasticsearch-6.6.0/plugins下 创建名为ik的目录
# 下载ik插件zip包
aaa@ops01 在 /opt/module/elasticsearch-6.6.0/plugins/ik 目录下 执行 ls 命令
用于Elasticsearch的ik分析器版本为6.6.0的压缩文件
# 解压缩安装包并清理zip文件
将elasticsearch - analysis - ik - 6.6.0.zip解压 然后删除elasticsearch - analysis - ik - 6.6.0.zip
# 目录结构
aaa@ops01 在 /opt/module/elasticsearch-6.6.0/plugins/ik 路径下 执行 ll 命令
total 1432
文件权限为rw-r--r--,所有者和所属组均为aaa,文件大小为263965字节,修改时间为2018年5月6日,文件名是commons-codec-1.9.jar
文件权限为rw-r--r--,所有者为aaa,所属组为aaa,文件大小为61829字节,修改时间为2018年5月6日,文件名是commons-logging-1.2.jar
文件权限为可读可写可执行,所有者和所属组均为aaa,文件大小为4096字节,日期是2018年8月26日,文件夹名为config
文件权限为rw-r--r--,所有者和所属组都是aaa,文件大小为54693字节,创建时间是2019年1月30日,文件名是elasticsearch-analysis-ik-6.6.0.jar
文件权限为rw-r--r--,所有者和所属组均为aaa,文件大小为736658字节,最后修改时间为2018年5月6日,文件名是httpclient-4.5.2.jar
文件权限为rw-r--r--,所有者是aaa,所属组是aaa,文件大小为326724字节,最后修改时间是2018年5月6日,文件名是httpcore-4.4.4.jar
文件权限为rw-r--r--,所有者和所属组均为aaa,文件大小为1805字节,最后修改时间是2019年1月30日,文件名是plugin-descriptor.properties
文件权限为rw-r--r--,所有者是aaa,所属组是aaa,文件大小为125字节,创建时间是2019年1月30日,文件名是plugin - security.policy
# 分发插件至其它节点
root@ops01:/opt/module/elasticsearch-6.6.0/plugins/ik进入上级目录 执行cd ..命令
root用户在ops01的/opt/module/elasticsearch-6.6.0/plugins目录下 通过scp命令 将ik文件夹 递归复制到ops02的/opt/module/elasticsearch-6.6.0/plugins/目录下
root用户在ops01的/opt/module/elasticsearch-6.6.0/plugins目录下 通过scp命令 将ik文件夹 递归复制到ops03的/opt/module/elasticsearch-6.6.0/plugins/目录下
测试使用ik中文分词
还有ik_max_word
ik_smart
逐个去匹配,每个字使用1次
ik_max_word
形成关系词
【注意】:从上面示例能够看出,不同的分词器,分词存在明显的区别。所以以后定义一个type时,不能再使用默认的mapping,要手工建立mapping来指定分词器。因为要依据使用场景选择适用合理的分词器
自定义中文词库
生活里 时常会冒出些新的热门词语 就像近期我接触频繁的yyds永远的神 要是一直用先前的词库 那像永远的神 可能会被拆分成 永远 的 神 而不是我们所期望的永远的神作为一个整体
那这种情况就需要维护一套用户自定义的中文词库。
在没有自定义中文词库时 我们先查一个示例 把结果留存 等安装完自定义词库后 用作对比
安装前:
安装部署自定义词库:
root用户在ops01服务器上 位于/opt/module/elasticsearch-6.6.0/plugins/ik/config目录下 执行pwd命令
/opt/module/elasticsearch - 6.6.0插件目录下的ik配置文件夹
root用户在ops01的/opt/module/elasticsearch-6.6.0/plugins/ik/config目录下执行ls命令
额外主词典 额外单字词典 额外单字全拼词典 额外低频单字词典 额外停用词词典 IK分析器配置文件 主词典 介词词典 量词词典 停用词词典 后缀词典 姓氏词典
修改ik插件的config目录下的IKAnalyzer.cfg.xml配置文件
# 这是一个网址链接:http://192.168.1.234/fenci/esword.txt 这行配置一个nginx代理地址
root用户在ops01的/opt/module/elasticsearch-6.6.0/plugins/ik/config目录下 执行vim命令 编辑IKAnalyzer.cfg.xml文件
IK Analyzer 扩展配置
http://192.168.1.234/fenci/esword.txt
切换到有nginx服务的机器。若没有nginx,需自行部署安装
root@ops04:/usr/local/nginx-1.10/conf#进入/usr/local/nginx-1.10/目录
root用户在ops04的/usr/local/nginx - 1.10目录下执行创建ik目录的操作
root@ops04:/usr/local/nginx - 1.10#进入ik目录
root用户在ops04服务器的/usr/local/nginx-1.10/ik目录下执行创建名为fenci的目录的操作
root@ops04:/usr/local/nginx - 1.10/ik#进入fenci目录
root@ops04:/usr/local/nginx-1.10/ik/fenci #将“王亭”这个内容输出到esword.txt文件中 具体操作为echo "王亭" 然后重定向到esword.txt文件 即>> esword.txt
root用户在ops04的/usr/local/nginx-1.10/ik/fenci目录下 将“永远的神”输入到esword.txt文件中 执行echo命令 并将结果重定向到该文件
root@ops04:/usr/local/nginx-1.10/ik/fenci #将“神圣赞美诗”输入到esword.txt文件中
root用户在ops04主机的/usr/local/nginx-1.10/ik/fenci目录下执行cat命令查看esword.txt文件内容
王亭
永远的神
神圣赞美诗
root用户在ops04的/usr/local/nginx-1.10/ik/fenci目录下 使用vim编辑器打开 /usr/local/nginx-1.10/conf/nginx.conf文件
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
# 增加如下配置:
location /fenci/ {
root ik;
}
root用户在ops04的/usr/local/nginx-1.10/ik/fenci目录下 执行/usr/local/nginx-1.10/sbin/nginx -s reload命令
地址要与IKAnalyzer.cfg.xml配置项相对应。也可以先将nginx设置妥当,之后再对IKAnalyzer.cfg.xml进行配置,这样更合理。
root@ops01:/opt/module/elasticsearch-6.6.0/plugins/ik/config 执行curl命令 目标地址为http://192.168.1.234/fenci/esword.txt
王亭
永远的神
神圣赞美诗
# 修改的xml配置,分发至其它节点
root用户在ops01的/opt/module/elasticsearch-6.6.0/plugins/ik/config目录下 将IKAnalyzer.cfg.xml文件 通过scp命令 传输到ops02的/opt/module/elasticsearch-6.6.0/plugins/ik/config/目录中
root用户在ops01的/opt/module/elasticsearch-6.6.0/plugins/ik/config目录下 将IKAnalyzer.cfg.xml文件 通过scp命令 传输到ops03的/opt/module/elasticsearch-6.6.0/plugins/ik/config/目录中
# 重启es(各节点)
root@ops01:/opt/module/elasticsearch-6.6.0/plugins/ik/config 执行命令jps 查找包含Elasticsearch的进程 然后通过awk命令以空格为分隔符提取第一列内容
13077
root用户在ops01主机的/opt/module/elasticsearch-6.6.0/plugins/ik/config目录下执行命令 强制终止进程号为13077的进程
root@ops01:/opt/module/elasticsearch-6.6.0/plugins/ik/config进入到/opt/module/elasticsearch-6.6.0/bin/
root用户在ops01服务器的/opt/module/elasticsearch-6.6.0/bin目录下 执行./elasticsearch -d命令
重启es后重新再测试:(已经可以成功识别出新定义的词语)