写点什么

elasticsearch 安装和使用 ik 分词器

作者:程序员欣宸
  • 2022 年 8 月 01 日
  • 本文字数:4788 字

    阅读完需:约 16 分钟

elasticsearch安装和使用ik分词器

欢迎访问我的 GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos


  • 在使用 elasticsearch 的时候,如果不额外安装分词器的话,在处理 text 字段时会使用 elasticsearch 自带的默认分词器,我们来一起看看默认分词器的效果;

环境信息

  • 本次实战用到的 elasticsearch 版本是 6.5.0,安装在 Ubuntu 16.04.5 LTS,客户端工具是 postman6.6.1;

  • 如果您需要搭建 elasticsearch 环境,请参考《Linux环境快速搭建elasticsearch6.5.4集群和Head插件》

  • Ubuntu 服务器上安装的 JDK,版本是 1.8.0_191;

  • Ubuntu 服务器上安装了 maven,版本是是 3.5.0;

elasticsearch 为什么要用 6.5.0 版本

  • 截止发布文章时间,elasticsearch 官网已经提供了 6.5.4 版本下载,但是 ik 分词器的版本目前支持到 6.5.0 版本,因此本次实战的 elasticsearch 选择了 6.5.0 版本;

基本情况介绍

  • 本次实战的 elasticsearch 环境已经搭建完毕,是由两个机器搭建的集群,并且 elasticsearch-head 也搭建完成:


  1. 一号机器,IP 地址:192.168.150.128;

  2. 二号机器:IP 地址:192.168.150.128;

  3. elasticsearch-head 安装在一号机器,访问地址:http://192.168.150.128:9100

数据格式说明

  • 为了便于和读者沟通,我们来约定一下如何在文章中表达请求和响应的信息:

  • 假设通过 Postman 工具向服务器发送一个 PUT 类型的请求,地址是:http://192.168.150.128:9200/test001/article/1

  • 请求的内容是 JSON 格式的,内容如下:


{  "id":1,  "title":"标题a",  "posttime":"2019-01-12",  "content":"一起来熟悉文档相关的操作"}
复制代码


  • 对于上面的请求,我在文章中就以如下格式描述:


PUT test001/article/1
{ "id":1, "title":"标题a", "posttime":"2019-01-12", "content":"一起来熟悉文档相关的操作"}
复制代码


  • 读者您看到上述内容,就可以在 postman 中发起 PUT 请求,地址是"test001/article/1"前面加上您的服务器地址,内容是上面的 JSON;

默认分词器的效果

  • 先来看看默认的分词效果:

  • 创建一个索引:


PUT test002
复制代码


  • 查看索引基本情况:


GET test002/_settings
复制代码


  • 收到响应如下,可见并没有分词器的信息:


{    "test002": {        "settings": {            "index": {                "creation_date": "1547863084175",                "number_of_shards": "5",                "number_of_replicas": "1",                "uuid": "izLzdwCQRdeq01tNBxajEg",                "version": {                    "created": "6050499"                },                "provided_name": "test002"            }        }    }}
复制代码


  • 查看分词效果:


POST test002/_analyze?pretty=true
{"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        },        {            "token": "软",            "start_offset": 3,            "end_offset": 4,            "type": "<IDEOGRAPHIC>",            "position": 3        },        {            "token": "件",            "start_offset": 4,            "end_offset": 5,            "type": "<IDEOGRAPHIC>",            "position": 4        },        {            "token": "工",            "start_offset": 5,            "end_offset": 6,            "type": "<IDEOGRAPHIC>",            "position": 5        },        {            "token": "程",            "start_offset": 6,            "end_offset": 7,            "type": "<IDEOGRAPHIC>",            "position": 6        },        {            "token": "师",            "start_offset": 7,            "end_offset": 8,            "type": "<IDEOGRAPHIC>",            "position": 7        }    ]}
复制代码


  • 为了词项搜索能得到我们想要的结果,需要换一个分词器,理想的分词效果应该是"我们"、"是"、"软件"、"工程师",ik 分词器可以满足我们的要求,接下来开始实战;

注意事项

下载 IK 分词器源码到 Ubuntu

  • 登录 ik 分词器网站:https://github.com/medcl/elasticsearch-analysis-ik

  • 按照网站提供的版本对应表,确认我们要使用的分词器版本,很遗憾写文章的时候还没有匹配 elasticsearch-6.5.0 的版本,那就用 master 吧,也就是下图中的红框版本:


  • 如下图,点击下载 zip 文件:


  • 将下载的 zip 包放到 Ubuntu 机器上,解压后是个名为 elasticsearch-analysis-ik-master 的文件夹,在此文件夹下执行以下命令,即可开始构建 ik 分词器工程:


mvn clean package -U -DskipTests
复制代码


  • 等待编译完成后,在 target/release 目录下会生产名为 elasticsearch-analysis-ik-6.5.0.zip 的文件,如下所示:


$ pwd/usr/local/work/es/elasticsearch-analysis-ik-master$ cd target/$ lsarchive-tmp  elasticsearch-analysis-ik-6.5.0.jar          generated-sources  maven-statusclasses      elasticsearch-analysis-ik-6.5.0-sources.jar  maven-archiver     releases$ cd releases/$ lselasticsearch-analysis-ik-6.5.0.zip
复制代码


  • 停止集群中所有机器的 elasticsearch 进程,在所有机器上做这些操作:在 elasticsearch 的 plugins 目录下创建名为 ik 的目录,再将上面生成的 elasticsearch-analysis-ik-6.5.0.zip 文件复制到这个新创建的 ik 目录下;

  • 在 elasticsearch-analysis-ik-6.5.0.zip 所在文件夹下,执行目录 unzip elasticsearch-analysis-ik-6.5.0.zip 进行解压;

  • 确认 elasticsearch-analysis-ik-6.5.0.zip 已经复制到每个 elasticsearch 的 plugins/ik 目录下并解压后,将所有 elasticsearch 启动,可以发现控制台上会输出 ik 分词器被加载的信息,如下图所示:


  • 至此,ik 分词器安装完成,来验证一下吧;

验证 ik 分词器

  • 在 postman 发起请求,在 json 中通过 tokenizer 指定分词器:


POST test002/_analyze?pretty=true
{"text":"我们是软件工程师","tokenizer":"ik_max_word"}
复制代码


  • 这一次得到了分词的效果:


{    "tokens": [        {            "token": "我们",            "start_offset": 0,            "end_offset": 2,            "type": "CN_WORD",            "position": 0        },        {            "token": "是",            "start_offset": 2,            "end_offset": 3,            "type": "CN_CHAR",            "position": 1        },        {            "token": "软件工程",            "start_offset": 3,            "end_offset": 7,            "type": "CN_WORD",            "position": 2        },        {            "token": "软件",            "start_offset": 3,            "end_offset": 5,            "type": "CN_WORD",            "position": 3        },        {            "token": "工程师",            "start_offset": 5,            "end_offset": 8,            "type": "CN_WORD",            "position": 4        },        {            "token": "工程",            "start_offset": 5,            "end_offset": 7,            "type": "CN_WORD",            "position": 5        },        {            "token": "师",            "start_offset": 7,            "end_offset": 8,            "type": "CN_CHAR",            "position": 6        }    ]}
复制代码


  • 可见所有可能形成的词语都被分了出来,接下试试 ik 分词器的另一种分词方式 ik_smart

  • 使用 ik_smart 方式分词的请求如下:


POST test002/_analyze?pretty=true
{"text":"我们是软件工程师","tokenizer":"ik_smart"}
复制代码


  • 这一次得到了分词的效果:


{    "tokens": [        {            "token": "我们",            "start_offset": 0,            "end_offset": 2,            "type": "CN_WORD",            "position": 0        },        {            "token": "是",            "start_offset": 2,            "end_offset": 3,            "type": "CN_CHAR",            "position": 1        },        {            "token": "软件",            "start_offset": 3,            "end_offset": 5,            "type": "CN_WORD",            "position": 2        },        {            "token": "工程师",            "start_offset": 5,            "end_offset": 8,            "type": "CN_WORD",            "position": 3        }    ]}
复制代码


  • 可见 ik_smart 的特点是将原句做拆分,不会因为各种组合出现部分的重复,以下是来自官方的解释:


ik_max_word 和 ik_smart 什么区别?ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。
复制代码

验证搜索

  • 前面通过 http 请求验证了分词效果,现在通过搜索来验证分词效果;

  • 通过静态 mapping 的方式创建索引,指定了分词器和分词方式:


PUT test003
{ "mappings": { "article": { "dynamic": false, "properties": { "title": { "type": "keyword" }, "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" } } } }}
复制代码


  • 创建成功会收到以下响应:


{    "acknowledged": true,    "shards_acknowledged": true,    "index": "test003"}
复制代码


  • 创建一个文档:


PUT test003/article/1
{ "id":1, "title":"文章一", "content":"我们是软件工程师"}
复制代码


  • 工程师作为关键词查询试试:


GET test003/_search
{ "query":{ "term":{"content":"工程师"} }}
复制代码


  • 搜索成功:


{    "took": 111,    "timed_out": false,    "_shards": {        "total": 5,        "successful": 5,        "skipped": 0,        "failed": 0    },    "hits": {        "total": 1,        "max_score": 0.2876821,        "hits": [            {                "_index": "test003",                "_type": "article",                "_id": "1",                "_score": 0.2876821,                "_source": {                    "id": 1,                    "title": "文章一",                    "content": "我们是软件工程师"                }            }        ]    }}
复制代码


  • 至此,ik 分词器的安装和使用实战就完成了,希望本文能在您的使用过程中提供一些参考;

欢迎关注 InfoQ:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

发布于: 刚刚阅读数: 3
用户头像

搜索"程序员欣宸",一起畅游Java宇宙 2018.04.19 加入

前腾讯、前阿里员工,从事Java后台工作,对Docker和Kubernetes充满热爱,所有文章均为作者原创,个人Github:https://github.com/zq2599/blog_demos

评论

发布
暂无评论
elasticsearch安装和使用ik分词器_Java_程序员欣宸_InfoQ写作社区