1)分词的概念

分词Search是一个构建于Lucene之上的优秀的分布式全文检索引擎(服务器),它是使用Java开发的,提供基于RESTful风格的Web服务接口。表面上我们只要将一段冗长的要检索的目标数据和一串关键字文本丢给它就完事了,事实上ES却不是直接使用完整的关键字文本在完整的目标数据中查找的,它们都要经过一个步骤:拆分成一个个单词、字或词组。

2)了解ES中的分词器(Analyzer)

ES中文本的拆分或者说分词是通过分词器完成的,ES中的分词器主要有standard(ES的默认分词器,将单词转成小写形式,去除标点符号,支持中文【单字分割】)、simple(通过非字母的字符分割文本,将单词转为小写形式,同时去除数字类型的字符)和whitespace(仅去除空格,不支持中文)。当然ES中的分词器不止这些,这里不再一一列举。

3)使用ES中的分词功能

为了直观的看到ES的分词情况,我们可以使用工具对ES发送一些分词请求,看看ES对不同文本的分词结果。

使用standard分词器

首先使用ES中的standard分词器,它也是ES中默认的分词器。我们可以发送一个URL为localhost:9200/_analyze的post请求,然后在请求体中填入如下JSON数据:

{"analyzer": "standard","text": "I bought a computer,8761元"
}

解释:analyzer字段指定需要的分词器,这里我们使用的是standard分词器(支持中文,简单按字分词),它是支持中文分词的;text字段指定要拆分的文本,这里是"I bought a computer,8761元";

执行结果如下,可以看到ES分词器为我们拆分成了六个最小词元(逗号被去掉了,同时所有的字母都转为小写),中文包含在内:

{"tokens": [{"token": "i","start_offset": ,"end_offset": 1,"type": "<ALPHANUM>","position": },{"token": "bought","start_offset": 2,"end_offset": 8,"type": "<ALPHANUM>","position": 1},{"token": "a","start_offset": 9,"end_offset": 10,"type": "<ALPHANUM>","position": 2},{"token": "computer","start_offset": 11,"end_offset": 19,"type": "<ALPHANUM>","position": 3},{"token": "8761","start_offset": 20,"end_offset": 24,"type": "<NUM>","position": 4},{"token": "元","start_offset": 24,"end_offset": 25,"type": "<IDEOGRAPHIC>","position": 5}]
}

使用simple分词器

同样的JSON数据,我们把analzer改成simple分词器:

{"analyzer": "simple","text": "I bought a computer,8761元"
}

返回结果变成了五个词元,可以看到simple分词器也是支持中文分词的,但是注意标点符号与数字都被去除了,同时所有字母转小写:

{"tokens": [{"token": "i","start_offset": ,"end_offset": 1,"type": "word","position": },{"token": "bought","start_offset": 2,"end_offset": 8,"type": "word","position": 1},{"token": "a","start_offset": 9,"end_offset": 10,"type": "word","position": 2},{"token": "computer","start_offset": 11,"end_offset": 19,"type": "word","position": 3},{"token": "元","start_offset": 24,"end_offset": 25,"type": "word","position": 4}]
}

使用whitespace分词器

analyzer值改为whitespace:

{"analyzer": "whitespace","text": "I bought a computer,8761元"
}

whitespace分词器是通过空白符,包括空格、制表符等分割文本的,同时它不会对单词转小写,重要的是它不支持中文的分词,所以从返回结果中我们可以看到最后一个中文字没有被拆分,这里顺便提一下,这里我使用的是全角(中文)逗号,并不是逗号后面还有一个空格,因为不支持中文,自然也是不支持中文符号的:

{"tokens": [{"token": "I","start_offset": ,"end_offset": 1,"type": "word","position": },{"token": "bought","start_offset": 2,"end_offset": 8,"type": "word","position": 1},{"token": "a","start_offset": 9,"end_offset": 10,"type": "word","position": 2},{"token": "computer,8761元","start_offset": 11,"end_offset": 25,"type": "word","position": 3}]
}

4)ES默认中文分词的缺陷

上面我们提到了,standard是ES中的默认分词器,但是对于中文来说只是按字拆分的结果我们能够接受吗?能不能再进一步呢?英文单词可以按照一个个词汇拆分,这是没有任何问题的,拿上面的例子来说,“computer”这个单词专业的术语叫“计算机”,但是如果使用默认的分词器来拆分“计算机”,我们看一下结果:

请求体

{"analyzer": "standard","text": "computer 计算机"
}

请求结果

{"tokens": [{"token": "computer","start_offset": ,"end_offset": 8,"type": "<ALPHANUM>","position": },{"token": "计","start_offset": 9,"end_offset": 10,"type": "<IDEOGRAPHIC>","position": 1},{"token": "算","start_offset": 10,"end_offset": 11,"type": "<IDEOGRAPHIC>","position": 2},{"token": "机","start_offset": 11,"end_offset": 12,"type": "<IDEOGRAPHIC>","position": 3}]
}

通过英语单词"computer"我们可以知道一个具体的事物,但是被按字拆分的“计算机”我们已经无法准确知道它要表达什么了,如果它能够更智能一点能够知道“计算机”这三个字所表达的含义,在将这三个字拆分的同时,自动为我们额外保留这三个字为最小词元,结果是不是更好一些呢?

5)IK中文分词器的安装&使用

要解决上面的问题我们可以通过IK分词器做到,IK分词器是通过字典的方式去理解我们日常中一些特定的短语词汇从而为我们保留一些有意义的短语的。

安装

我ES的版本是7.3.2,那么要找的IK也是7.3.2。找到合适的版本下载压缩包文件后解压(我下载的是.zip结尾的源码文件,这里需要使用maven打包),进到解压的文件夹下,执行mvn package打包命令,出现错误Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:2.6:resources (default-resources) on project elasticsearch-analysis-ik: Cannot create resource output directory: /home/tiny/Downloads/programs/elasticsearch-analysis-ik/target/classes

mvn打包出现错误

执行命令sudo chown -R tiny:tiny ../elasticsearch-analysis-ik后再次执行mvn package,成功:

mvn打包成功

进到elasticsearch-analysis-ik/target/releases目录,使用命令sudo unzip elasticsearch-analysis-ik-7.0.0.zip解压,而后将解压出来的所有文件复制到ElasticSearch文件夹的plugins/ik(没有就新建)目录下,之后重启ES。

ik分词器放置目录

IK安装后导致ES无法启动

意料之外的是ES启动居然报错了,打印了一些日志,主要看框起的一行,大致是说:“IK是为ElasticSearch7.0.0构建的但是7.3.2版本的ElasticSearch正在运行”。如果你没看明白,回过头看看我们解压的文件elasticsearch-analysis-ik-7.0.0.zip也该知道了,确实是7.0.0版本!

安装ik后ES启动失败

这可能是7.3.2版本的一个BUG?我确实下载的是IK的7.3.2版本后打包编译的,但居然打包出一个7.0.0版本的IK文件。关于ES的版本问题,我尝试着到IK项目的pom.xml文件中查看ES的版本:

查看ik项目的pom文件

可以看到ES的版本标注的是7.0.0,我尝试着将pom文件中ES的版本改为7.3.2,保存退出,然后执行mvn clean package,出现错误:

mvn清理并打包出现错误

问题不大,我们手动将target目录删除,然后mvn package,执行成功了,可以看到版本已经是7.3.2:

打包成功

之后再按照之前的步骤解压并复制到ES下的plugins/ik目录(记得把二手手游账号买卖平台ik目录清空再复制),启动ES:

ES启动成功

终于成功了,太艰难了/(ㄒoㄒ)/~~

使用IK中文分词器

ES启动完成后我们来测试一下使用IK分词器分词,看看IK分词器是否安装成功了。同样请求URL还是localhost:9200/_analyze,请求方法还是post,对于各个分词器就不再赘述了,请通过示例自行感受!

ik_smart分词器

请求体

{"analyzer": "ik_smart","text": "我买了一台计算机"
}

响应结果

{"tokens": [{"token": "我","start_offset": ,"end_offset": 1,"type": "CN_CHAR","position": },{"token": "买了","start_offset": 1,"end_offset": 3,"type": "CN_WORD","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_max_word分词器

请求体

{"analyzer": "ik_max_word","text": "我买了一台计算机"
}

响应结果

{"tokens": [{"token": "我","start_offset": ,"end_offset": 1,"type": "CN_CHAR","position": },{"token": "买了","start_offset": 1,"end_offset": 3,"type": "CN_WORD","position": 1},{"token": "一台","start_offset": 3,"end_offset": 5,"type": "CN_WORD","position": 2},{"token": "一","start_offset": 3,"end_offset": 4,"type": "TYPE_CNUM","position": 3},{"token": "台","start_offset": 4,"end_offset": 5,"type": "COUNT","position": 4},{"token": "计算机","start_offset": 5,"end_offset": 8,"type": "CN_WORD","position": 5},{"token": "计算","start_offset": 5,"end_offset": 7,"type": "CN_WORD","position": 6},{"token": "算机","start_offset": 6,"end_offset": 8,"type": "CN_WORD","position": 7}]
}

6)IK分词器为何如此智能

通过上面的示例我们也看到了,这种中文的分词效果是ES内置的分词器无法比拟的。那么它是如何做到的呢?不要过于惊讶,因为原理其实非常简单,它是通过索引字典来达到的,这样说可能比较抽象难懂,我们来实际看看ES的plugins/ik/config目录:

ik分词器的字典

看到那些*.dic结尾的文件了吗?其实它就是dictionary(字典)的简写,来实际看看字典内容:

ik分词器的字典内容

实际的词汇量是非常巨大的,根本不可能完全收录到字典中。如果有需要,我们完全可以通过在字典文件中增加我们想要的词语来扩展我们自己的分词规则。

7)如何在实际项目中使用分词器

上面我们通过HTTP的形式知道了ES是如何分词的,但是在实际项目中又该如何使用?有了Spring Boot,一切都变得非常简单,Spring Boot集成了众多框架,并对其繁琐的操作进行简化。要在Spring Boot项目中集成ES,我们只需要引入如下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>

然后就可以在Java类中使用注解的方式定义:

@Data
// 指定实体类对应ES的索引名称为article,类型type是文档类型,使用服务器远程配置
// 为避免每次重启项目都将ES中的数据删除后再同步,createIndex指定为false
@Document(indexName = "article", type = "_doc",useServerConfiguration = true, createIndex = false)
public class ElasticArticle {@Id // org.springframework.data.annotation.Idprivate Integer id;          // 文章ID// 指定字段对应的ES类型是Text,analyzer指定分词器为ik_max_word@Field(type = FieldType.Text, analyzer = "ik_max_word")private String author;       // 文章作者@Field(type = FieldType.Text, analyzer = "ik_max_word")private String title;        // 文章标题@Field(type = FieldType.Text, analyzer = "ik_max_word")private String content;      // 文章正文内容// 指定字段对应ES中的类型是Date,使用自定义的日期格式化,pattern指定格式化// 规则是“日期时间”或“日期”或“时间毫秒”@Field(type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")private Date createTime;     // 文章创建时间@Field(type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")private Date updateTime;     // 文章更新时间
}

在与ES的交互方面,Spring Boot Data提供了ElasticsearchRepository数据访问接口,我们只需继承此接口便可实现与ES的大部分交互,就像使用Spring-Data-JPA一样简单!

ElasticSearch学习笔记(分词器的介绍使用)相关推荐

  1. ElasticSearch学习 ④ IK分词器(elasticsearch插件)+自定义字典

    ES默认的分词器把中文每个字看作一个词,比如说:"我爱喝水"会被划分为"我","爱","喝","水" ...

  2. ElasticSearch学习----IK分词器

    IK分词器 一. IK分词器 ①. 在线安装IK 1. 必须将ElasticSearch服务中原始数据删除 2. 在ElasticSearch安装目录中执行如下命令 2. 重启ElasticSearc ...

  3. ElasticSearch学习笔记之十一 Anayle API和IK分词器

    ElasticSearch学习笔记之十一 Anayle API和IK分词器 Anayle API IK分词器 IK分词器版本支持 安装 下载或者编译 选择一 选择二 重启ElasticSearch I ...

  4. Elasticsearch之Analyzer分词器介绍

    Elasticsearch之Analyzer分词器介绍 Analysis Analyzer的组成 ES中内置的分词器 Analyzer的使用 几种分词器介绍 Standard Analyzer Sim ...

  5. 狂神说ElasticSearch学习笔记

    在学习ElasticSearch之前,先简单了解一下Lucene: Doug Cutting开发 是apache软件基金会4 jakarta项目组的一个子项目 是一个开放源代码的全文检索引擎工具包 不 ...

  6. ElasticSearch学习笔记(8)· ES集群的搭建

    目录 十三.集群的实现 1.相关概念 集群(cluster) 节点(node) 分配和复制(shards & replicas) 2.快速搭建集群 3.安装head插件 十三.集群的实现 1. ...

  7. 黑马程序员--分布式搜索ElasticSearch学习笔记

    写在最前 黑马视频地址:https://www.bilibili.com/video/BV1LQ4y127n4/ 想获得最佳的阅读体验,请移步至我的个人博客 SpringCloud学习笔记 消息队列M ...

  8. 2021年大数据ELK(八):Elasticsearch安装IK分词器插件

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 安装IK分词器 一.下载Elasticsearch IK分词器 ...

  9. HTML/CSS学习笔记01【概念介绍、基本标签】

    w3cschool菜鸟教程.CHM(腾讯微云):https://share.weiyun.com/c1FaX6ZD HTML/CSS学习笔记01[概念介绍.基本标签.表单标签][day01] HTML ...

  10. 04.ElasticSearch之IK分词器的安装与使用

    ElasticSearch之IK分词器的安装与使用 前言 安装 离线安装 在线安装 ik分词器测试 扩展(停用)词(典) 测试数据 概念 配置词典 1.修改配置文件 2.新建词典 3.自定义内容 4. ...

最新文章

  1. PHP - 如何解决中文乱码
  2. 程序员幽默:39个奇葩代码注释,看完笑哭了
  3. arcgis按属性设置符号大小
  4. dumpsys gfxinfo packacges计算帧率
  5. 阿里春招Android面经
  6. 三大有限元分析软件(ABAQUS、ANSYS、MSC)的优缺点是什么?应如何选择?
  7. Charles弱网测试
  8. 今天给大家分享的案例就是关于电影的啦,我们一起来看看IMDBtop10000的电影排行榜数据
  9. 一种特殊的魔方阵解法
  10. Linux 多点电容触摸屏
  11. winpython, anaconda 哪个更好?
  12. discard是什么意思啊(discard是什么意思翻译)
  13. 飞思卡尔 s19 转 bin
  14. c# MouseClick和MouseDown的区别
  15. 线性代数二次型标准化的方法总结
  16. 免费的几个CDN加速
  17. markdown基本语法.md
  18. 十年磨一剑,云原生分布式数据库PolarDB-X的核心技术演化
  19. 【工具分享】免杀360火绒的shellcode加载器
  20. 知己知彼,你的网红营销策略才能百战百胜

热门文章

  1. 张朝阳对话彭凯平:大脑有可塑性 人可以从原生家庭走出来
  2. 1500套HTML+CSS+JS网页设计期末课程大作业 web前端开发技术 web课程设计 网页规划与设计
  3. iOS应用如何防止被反编译
  4. 市场掀起新猜度:当代置业也要暴雷?
  5. 防火墙软件firewall使用
  6. java自动铅笔,彩铅6步画出奥黛丽赫本经典造型
  7. 虚拟机账号密码忘记了怎么办_宽带账号密码忘记怎么办?学会这招轻松帮你找回...
  8. Outlook 2007 设置邮件数字证书的方法
  9. ipvsadm 命令
  10. Untitled Diagram绘画E-R图