ES 终于能够搜到”悟空哥“了!

zhi'ci回复 PDF 领取资料 html

这是悟空的第 90 篇原创文章
java

做者 | 悟空聊架构nginx

来源 | 悟空聊架构(ID:PassJava666)git

转载请联系受权(微信ID:PassJava)

Elasticsearch(简称 ES)的搜索引擎内置了不少种分词器,可是对中文分词不友好,好比搜索悟空哥,是搜不到的,因此咱们须要借助第三方中文分词工具包。github

悟空哥专门研究了下 ik 中文分词工具包该怎么玩,但愿对你们有所帮助。web

本文主要内容以下:docker

主要内容

1 ES 中的分词的原理

1.1 ES 的分词器概念

ES 的一个分词器 ( tokenizer ) 接收一个字符流,将其分割为独立的词元 ( tokens ) ,而后输出词元流。vim

ES 提供了不少内置的分词器,能够用来构建自定义分词器 ( custom ananlyzers )浏览器

1.2 标准分词器原理

好比 stadard tokenizer 标准分词器,遇到空格进行分词。该分词器还负责记录各个词条 ( term ) 的顺序或 position 位置 ( 用于 phrase 短语和 word proximity 词近邻查询 ) 。每一个单词的字符偏移量 ( 用于高亮显示搜索的内容 ) 。bash

1.3 英文和标点符号分词示例

查询示例以下:

POST _analyze
{
  "analyzer""standard",
  "text""Do you know why I want to study ELK? 2 3 33..."
}

查询结果:

do, you, know, why, i, want, to, study, elk, 2,3,33

从查询结果能够看到:

(1)标点符号没有分词。

(2)数字会进行分词。

英文句子分词

1.4 中文分词示例

可是这种分词器对中文的分词支持不友好,会将词语分词为单独的汉字。好比下面的示例会将 悟空聊架构 分词为 ,,,,,指望分词为 悟空架构

POST _analyze
{
  "analyzer""standard",
  "text""悟空聊架构"
}
中文分词悟空聊架构

咱们能够安装 ik 分词器来更加友好的支持中文分词。

2  安装 ik 分词器

2.1 ik 分词器地址

ik 分词器地址:

https://github.com/medcl/elasticsearch-analysis-ik/releases

先检查 ES 版本,我安装的版本是 7.4.2,因此咱们安装 ik 分词器的版本也选择 7.4.2

http://192.168.56.10:9200/
{
  "name" : "8448ec5f3312",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "xC72O3nKSjWavYZ-EPt9Gw",
  "version" : {
    "number" : "7.4.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96",
    "build_date" : "2019-10-28T20:40:44.881551Z",
    "build_snapshot" : false,
    "lucene_version" : "8.2.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
选择 ik 分词器

2.2 安装 ik 分词器的方式

2.2.1 方式一:容器内安装 ik 分词器

  • 进入 es 容器内部 plugins 目录
docker exec -it <容器 id> /bin/bash
  • 获取 ik 分词器压缩包
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
  • 解压缩 ik 压缩包
unzip 压缩包
  • 删除下载的压缩包
rm -rf *.zip

2.2.2 方式二:映射文件安装 ik 分词器

进入到映射文件夹

cd /mydata/elasticsearch/plugins

下载安装包

wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
  • 解压缩 ik 压缩包
unzip 压缩包
  • 删除下载的压缩包
rm -rf *.zip

2.2.3 方式三:Xftp 上传压缩包到映射目录

先用 XShell 工具链接虚拟机 ( 操做步骤能够参考以前写的文章 02. 快速搭建 Linux 环境-运维必备) ,而后用 Xftp 将下载好的安装包复制到虚拟机。

Xftp 上传压缩包

3 解压 ik 分词器到容器中

  • 若是没有安装 unzip 解压工具,则安装 unzip 解压工具。
apt install unzip
  • 解压 ik 分词器到当前目录的 ik 文件夹下。

命令格式:unzip <ik 分词器压缩包>

实例:

unzip ELK-IKv7.4.2.zip -d ./ik
解压 ik 分词器
  • 修改文件夹权限为可读可写。
chmod -R 777 ik/
  • 删除 ik 分词器压缩包
rm ELK-IKv7.4.2.zip

4 检查 ik 分词器安装

  • 进入到容器中
docker exec -it <容器 id> /bin/bash
  • 查看 Elasticsearch 的插件
elasticsearch-plugin list

结果以下,说明 ik 分词器安装好了。是否是很简单。

ik
ik 分词器插件

而后退出 Elasticsearch 容器,并重启 Elasticsearch 容器

exit
docker restart elasticsearch

5 使用 ik 中文分词器

ik 分词器有两种模式

  • 智能分词模式 ( ik_smart )

  • 最大组合分词模式 ( ik_max_word )

咱们先看下 智能分词 模式的效果。好比对于 一颗小星星 进行中文分词,获得的两个词语:一颗小星星

咱们在 Dev Tools Console 输入以下查询

POST _analyze
{
  "analyzer""ik_smart",
  "text""一颗小星星"
}

获得以下结果,被分词为 一颗和小星星。

一颗小星星分词结果

再来看下 最大组合分词模式。输入以下查询语句。

POST _analyze
{
  "analyzer""ik_max_word",
  "text""一颗小星星"
}

一颗小星星 被分红了 6 个词语:一颗、1、颗、小星星、小星、星星。

一颗小星星分词结果

咱们再来看下另一个中文分词。好比搜索悟空哥聊架构,指望结果:悟空哥、聊、架构三个词语。

实际结果:悟、空哥、聊、架构四个词语。ik 分词器将悟空哥分词了,认为 空哥 是一个词语。因此须要让 ik 分词器知道 悟空哥 是一个词语,不须要拆分。那怎么办作呢?

悟空哥聊架构分词

6 自定义分词词库

6.1 自定义词库的方案

  • 方案

    新建一个词库文件,而后在 ik 分词器的配置文件中指定分词词库文件的路径。能够指定本地路径,也能够指定远程服务器文件路径。这里咱们使用远程服务器文件的方案,由于这种方案能够支持热更新 ( 更新服务器文件,ik 分词词库也会从新加载 ) 。

  • 修改配置文件

ik 分词器的配置文件在容器中的路径:

/usr/share/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml。

修改这个文件能够经过修改映射文件,文件路径:

/mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml

编辑配置文件:

vim /mydata/elasticsearch/plugins/ik/config/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>

修改配置 remote_ext_dict 的属性值,指定一个 远程网站文件的路径,好比 http://www.xxx.com/ikwords.text。

这里咱们能够本身搭建一套 nginx 环境,而后把 ikwords.text 放到 nginx 根目录。

6.2 搭建 nginx 环境

方案:首先获取 nginx 镜像,而后启动一个 nginx 容器,而后将 nginx 的配置文件拷贝到根目录,再删除原 nginx 容器,再用映射文件夹的方式来从新启动 nginx 容器。

  • 经过 docker 容器安装 nginx 环境。
docker run -p 80:80 --name nginx -d nginx:1.10
  • 拷贝 nginx 容器的配置文件到 mydata 目录的 conf 文件夹
cd /mydata
docker container cp nginx:/etc/nginx ./conf
  • mydata 目录 里面建立 nginx 目录
mkdir nginx
  • 移动 conf 文件夹到 nginx 映射文件夹
mv conf nginx/
  • 终止并删除原 nginx 容器
docker stop nginx
docker rm <容器 id>
  • 启动新的容器
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
  • 访问 nginx 服务
192.168.56.10

报 403 Forbidden, nginx/1.10.3 则表示 nginx 服务正常启动。403 异常的缘由是 nginx 服务下没有文件。

  • nginx 目录新建一个 html 文件
cd /mydata/nginx/html
vim index.html
hello passjava
  • 再次访问 nginx 服务

    浏览器打印 hello passjava。说明访问 nginx 服务的页面没有问题。

  • 建立 ik 分词词库文件

cd /mydata/nginx/html
mkdir ik
cd ik
vim ik.txt

填写 悟空哥,并保存文件。

  • 访问词库文件
http://192.168.56.10/ik/ik.txt

浏览器会输出一串乱码,能够先忽略乱码问题。说明词库文件能够访问到。

  • 修改 ik 分词器配置
cd /mydata/elasticsearch/plugins/ik/config
vim IKAnalyzer.cfg.xml
修改 ik 分词器配置
  • 重启 elasticsearch 容器并设置每次重启机器后都启动 elasticsearch 容器。
docker restart elasticsearch
docker update elasticsearch --restart=always
  • 再次查询分词结果

能够看到 悟空哥聊架构 被拆分为 悟空哥架构 三个词语,说明自定义词库中的 悟空哥 有做用。

终于能够搜到 悟空哥 了~ ‍‍‍‍‍‍‍‍‍‍‍‍‍‍

- END -

写了两本 PDF, 回复  分布式  或  PDF  载。
个人 JVM 专栏已上架,回复  JVM  领取
我的网站: www.passjava.cn

我是悟空,努力变强,变身超级赛亚人!

本文分享自微信公众号 - 悟空聊架构(PassJava666)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索