龙空技术网

IK 分词器和ElasticSearch集成使用

JAVA大神周瑜 1497

前言:

而今看官们对“java中文分词算法”大约比较注意,你们都需要学习一些“java中文分词算法”的相关文章。那么小编也在网上搜集了一些关于“java中文分词算法””的相关内容,希望姐妹们能喜欢,朋友们快快来了解一下吧!

上述查询存在问题分析

在进行字符串查询时,我们发现去搜索"搜索服务器"和"搜索"都可以搜索到数据;

而在进行词条查询时,我们搜索"搜索"却没有搜索到数据;

究其原因是ElasticSearch的标准分词器导致的,当我们创建索引时,字段使用的是标准分词器:

例如对 "我是程序员" 进行分词

标准分词器分词效果测试:

POST 

请求体:

{  "analyzer": "standard",     "text": "我是程序员"}

分词结果:

而我们需要的分词效果是:我、是、程序、程序员

这样的话就需要对中文支持良好的分析器的支持,支持中文分词的分词器有很多,word分词器、庖丁解牛、盘古分词、Ansj分词等,但我们常用的还是下面要介绍的IK分词器。

IK分词器简介

IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目Lucene为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0则发展为 面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。

IK分词器3.0的特性如下:

1)采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力。

2)采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。

3)对中英联合支持不是很好,在这方面的处理比较麻烦.需再做一次查询,同时是支持个人词条的优化的词典存储,更小的内存占用。

4)支持用户词典扩展定义。

5)针对Lucene全文检索优化的查询分析器IKQueryParser;采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。

ElasticSearch集成IK分词器

IK分词器的安装

1)下载地址:

前面的文章也提供了IK分词器的压缩包:

2)解压,将解压后的elasticsearch文件夹拷贝到elasticsearch-6.5.2\plugins下,并重命名文件夹为ik

3)重新启动ElasticSearch,即可加载IK分词器

IK分词器测试

IK提供了两个分词算法ik_smart 和 ik_max_word

其中 ik_smart 为最少切分,ik_max_word为最细粒度划分

我们分别来试一下

1)最小切分:在浏览器地址栏输入地址

POST 

请求体:

{  "analyzer": "ik_smart",    "text": "我是程序员"}

输出的结果为:

2)最细切分:在浏览器地址栏输入地址

POST 

请求体:

{   "analyzer": "ik_smart",     "text": "我是程序员" }

输出的结果为:

修改索引映射mapping

重建索引

删除原有blog索引

DELETE localhost:9200/blog

创建blog索引,此时分词器使用ik_max_word

PUT localhost:9200/blog

请求体:

创建文档

POST localhost:9200/blog/article/1

请求体:

再次测试queryString查询

请求url:

POST localhost:9200/blog/article/_search

请求体:

postman截图:

将请求体搜索字符串修改为"钢索",再次查询:

postman截图:

再次测试term测试

请求url:

POST localhost:9200/blog/article/_search

请求体:

postman截图:

索引查询

基本语法

这里的query代表一个查询对象,里面可以有不同的查询属性

查询类型:

例如: match_all , match , term , range 等等

查询条件:查询条件会根据类型的不同,写法也有差异,后面详细讲解

查询所有数据(match_all)

基本语法

请求url:

GET 

postman截图:

匹配查询(match)

基本语法:

请求url:

GET 

请求体:

postman截图:

如果查询名称包含电视的,结果为三星电视和小米电视两条结果如果我们查询“小米电视”会有几条记录被查询出来呢?你可能说会有一条,但我们测试一 下会看到结果为小米电视、三星电视、小米手机三条结果,这是为什么呢?这是因为在查询时,会先将搜索关键字进行分词,对分词后的字符串进行查询,只要是包含这些字符串的都是要被查询出来的,多个词之间是 or 的关系。 返回的结果中_score是对这条记录的评分,评分代表这条记录与搜索关键字的匹配度, 查询结果按评分进行降序排序。 比如我们刚才搜索“小米电视” ,那小米电视这条记录的 评分是最高的,排列在最前面。 如果我们需要精确查找,也就是同时包含小米和电视两个词的才可以查询出来,这就需要将操作改为 and 关系:

查询结果为小米电视一条记录了。

queryString查询语法:

多字段查询(multi_match)

multi_match 与 match类似,不同的是它可以在多个字段中查询。

基本语法:

postman截图:

词条匹配(term)

term查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串。

基本语法:

多词条查询(terms)

terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这

个文档满足条件。

基本语法:

postman截图:

布尔组合(bool)

bool 把各种其它查询通过 must (与)、 must_not (非)、 should (或)的方式进行组合。

基本语法:

must :

postman截图:

should :

postman截图:

过滤查询

过滤是针对搜索的结果进行过滤,过滤器主要判断的是文档是否匹配,不去计算和判断文档的匹配度得分,所以过滤器性能比查询要高,且方便缓存,推荐尽量使用过滤器去实现查询或者过滤器和查询共同使用。

基本语法:

postman截图:

分组查询(聚合查询)

基本语法:

postman截图;

实在是太特么多了~~~有不同意见的欢迎在下面评论哈,创作不易,还请各位看官多多转发评论

标签: #java中文分词算法