分词器选择

调研了几种分词器,例如IK分词器,ansj分词器,mmseg分词器,发现IK的分词效果最好。举个例子:

词:<>哈撒多撒ئۇيغۇر تىلى王者荣耀sdsd@4342啊啊啊

Standard: 是,的,span,哈,span,撒,多,撒,ئۇيغۇر,تىلى,王,者,荣,耀,sdsd,4342,啊,啊,啊,啊

mmseg_maxword:是,的,span,哈,span,撒,多,撒,ئ,ۇ,ي,غ,ۇ,ر,ت,ى,ل,ى,王者,荣耀,sdsd,4342,啊,啊,啊,啊

IK_max_word:是的,span,哈,span,撒,多,撒,王者,王,者,荣耀,荣,耀,sdsd,4342,sdsd@4342,啊啊啊,啊啊,啊,啊啊,啊

Ansj: ,>,,哈,,撒,多,撒,ئ,ۇ,ي,غ,ۇ,ر,ت,ى,ل,ى,王者,荣耀,sdsd,@,4342,啊,啊,啊,啊

在上述例子中,IK和Mmsg 用的同一套词典。Ansj和IK,Mmsg使用的不是一套词典,也没有配置停词。

本文讲的中文分词器就是IK分词器。

分词器需要达到的效果

1)短语可以精确匹配

2)查找时间要比standard少

3)如果查找的词语不在词典中,也必须要查到

4)如果数据在原文中出现,就一定要查全

IK分词器短语精确匹配的问题

楼主意淫着将所有的单字放入词典中,这样用ik_max_word 对数据建索引时既可以把词分出来建索引,又可以把字分出来建索引。然后用 ik_smart 将查找短语,因为ik_smart分出的数据是 ik_max_word 的一个子集,如果要查找的短语在原文中有出现,那么一定可以查到。后来发现用ik_smart分词器查找句子(match_phrase)时一个都没有查到,exo???为什么会查不到呢?明明是一个子集。对此官方网站对match_phrase的解释如下:

Like the match query, the match_phrase query first analyzes the query string to produce a list of terms. It then searches for all the terms, but keeps only documents that contain all of the search terms, in the same positions relative to each other.

意思就是说用match_phrase查找时,查找分词器分出的词的位置和要建索引时分出的词的位置一样。举个例子:

原文:快乐感恩

ik_max_word:快乐 1 快 2 乐感 3 乐 4 感恩 5 感 6 恩 7

ik_smart:快乐 1 感恩 2

从上面可以看出,查找时ik_smart将语句分为了快乐和感恩两个词,位置分别为1和2,而ik_max_word建索引时,快乐和感恩的位置分别是1和4,在match_phrase看来,这种是不匹配的,所以用ik_smart分词短语时无法查到或者查全数据。

好吧,既然ik_smart无法查到,我用ik_max_word查找总行了吧。用上述的例子,查找”快乐“时,你会发现你用ik_max_word查找到的结果没有standard分词器建索引查找获取到的结果多。原因和上述讲的一样:

查找词语:快乐

ik_max_word:快乐 1 快 2 乐 3

在构建索引的时候,快乐,快和乐的位置分别是1,2,4,而查找时分词的顺序是1,2,3,然后match_phrase认为其不匹配,因此查询不到这种结果。

网上答案

遇到问题了,在网上寻求解决方案。看了几篇博客,都指出了match_phrase的这个匹配问题,解决方案有以下两种:

1) standard分词器

2) NGram分词器

standard分词器大家都比较熟,针对于汉字就是一个一个分,这种肯定是可以查全的。但一个一个字分的话,每个字对应的文档集合非常多,如果数据量达到了百亿,在求交集,计算距离时,效果非常差。

Ngram分词器类似于standard分词器,他可以指定分词的长度,然后用standard的方法切割。比如说“节日快乐”,我们指定切割的长度为2,NGram会切成“节日”,“日快”,“快乐”。虽然查找时可以减少每个token对应的文档数,但是存储量会增大很多,而且不在支持模糊的match匹配。很土。

求解过程

ik_max_word构建索引,ik_smart无法查找,原因是ik_max_word分出了所有的词,ik_smart只分出了一种词,由于match_phrase本身的限制导致ik_smart查找不到。那我构建的时候采用ik_smart,查找的时候也用ik_smart,这样只要原文中有数据,构建和查找用同一种分词方法,就应该可以查找得到。测试后发现,这种也有很大的问题,即像“潜行者”这样的词,只分为了“潜行”和“者”两个token,但是“行者”也是一个词,在查找“行者”时无法查全数据。

ik_smart无法查全的原因是只分出了一种词的可能性,导致有些词查询不全。ik_max_word能解决这个问题。。但是ik_max_word的问题是如果查找的最后一个字能和原文中这个字的下一个字组成词语,那么就会出现无法查全的问题。我们能不能让ik_max_word将词和字分开?

当然可以,对一个属性指定两种分词方法:

curl -XPUT 'xxx/my_test_both?pretty' -H 'Content-Type: application/json' -d'

{"mappings": {

"my_type": {

"properties": {

"ulluin": {

"type": "text",

"fields": {

"ik":{"type":"text","analyzer": "ik_max_word"}

}

}

}

}

}

}'

这样ulluin属性采用standard分词,即单字分词,ulluin.ik采用ik_max_word即按词分词,ik_max_word的词典中去除所有的单字。

查询时先将查询短语分词,如果第一个token和最后一个token中存在一个字,那么这个字可能与原文中的下一个字或者上一个字组成词,导致ik_max_word无法查到,这时我们用standard分词器在ulluin中查询,如果第一个token和最后一个token都是词,那么说明可以在ik_max_word中查询。来吧,测试一下:

原文:节日快乐龙哥

ik_max_word:节日 1 快乐龙 2 快乐 3 龙哥 4

查询短语:节日快乐

ik_max_word:节日 1 快乐 2

为什么还是有问题?????ik_max_word查出的数据量比standard的少???还是因为match_phrase的限制,索引中“节日”和“快乐”的位置是1和3,而查找时“节日”和“快乐”的位置是1和2。这个问题很好解决,用match_phrase_prefix查询即可,即:

curl -XGET 'xxx/my_test_both/_search?pretty' -H 'Content-Type: application/json' -d'

{

"query": {

"match_phrase_prefix" : {

"ulluin" : {

"query" : "节日快乐"

}

}

},

"size":1

}'

上面还提到ik_max_word有一个问题是分出的词语比standard的多,我们过滤了单字分词后,这个效果就会有很大的提升。假设我们的词典没有四字分词,只有二三字。比如说

原词:中华人民共和国

修改前:中华,中,华人,华,人民,人,民,共和国,共和,和,国

修改后:中华,华人,人民,共和国,共和

可以看出,修改后的效果要比standard的效果好的多,不但token数变少了,而且每个token对应的文档数也大大的降低,减少了求交集的数据量和计算距离的数据量。

至此总算解决了ES中文分词切精确匹配的问题。

php es 短语精确搜索,ES中文分词器之精确短语匹配(解决了match_phrase匹配不全的问题)...相关推荐

  1. 基于php的Sphinx以及coreseek的全文搜索,中文分词的使用(一)

    基于php的Sphinx以及coreseek的全文搜索,中文分词的使用(一) ##1.sphinx简介 1.什么是sphinx Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检 ...

  2. lucene的建立索引,搜索,中文分词

    Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包. 现在最新的lucene已经更新到6.0版本了.但是这个最新版,需要适配jdk1.80以 ...

  3. 从头开始编写基于隐含马尔可夫模型HMM的中文分词器之一 - 资源篇

    首先感谢52nlp的系列博文(http://www.52nlp.cn/),提供了自然语言处理的系列学习文章,让我学习到了如何实现一个基于隐含马尔可夫模型HMM的中文分词器. 在编写一个中文分词器前,第 ...

  4. 怎么配置linux中es搜索的主机名,分布式搜索elasticsearch中文分词集成

    elasticsearch官方只提供smartcn这个中文分词插件,效果不是很好,好在国内有medcl大神(国内最早研究es的人之一)写的两个中文分词插件,一个是ik的,一个是mmseg的,下面分别介 ...

  5. es数据库集群以及中文分词

    ##1: 集群相关名词 1.集群健康状态 绿色: 所有数据都完整,并且副本数满足 黄色: 所有数据都完整,但是有的索引副本数不满足 红色: 有的数据不完整 2.节点类型 主节点: 负责调度数据分配到哪 ...

  6. 分布式搜索elasticsearch中文分词集成

    elasticsearch官方只提供smartcn这个中文分词插件,效果不是很好,好在国内有medcl大神(国内最早研究es的人之一)写的两个中文分词插件,一个是ik的,一个是mmseg的,下面分别介 ...

  7. Lucene全文检索_分词_复杂搜索_中文分词器

    1 Lucene简介 Lucene是apache下的一个开源的全文检索引擎工具包. 1.1 全文检索(Full-text Search)  1.1.1 定义 全文检索就是先分词创建索引,再执行搜索的过 ...

  8. 面向搜索的中文分词设计

    我开发的中文分词程序,开源发布 ,其实哪个中文分词的整体架构是比较糟糕的.架构是否优秀决定了很多构思无法实现,思考了比较久,最近准备开发第二版,抛弃以前的架构,重新实现.下面是一些设计和构思.计划是两 ...

  9. php智能搜索,WordPress中文分词与智能搜索

    问题 WordPress的搜索功能非常简陋,如果用户搜索"日语综合教程+第六册",WordPress会机械地构造一个wp_posts.post_title LIKE '%日语综合教 ...

最新文章

  1. pytorch的backward
  2. 一次SQL查询优化原理分析(900W+数据,从17s到300ms)
  3. hashmap 泛型_Java 基础 - 泛型
  4. js 中对象属性的特性
  5. 微型计算机的层次结构,计算机系统层次结构微程序级
  6. 初识RabbitMQ,附RabbitMQ+PHP演示实例(亲测通过)
  7. Android 开发笔记——通过 Intent 传递类对象
  8. TypeScript里的类型为any和泛型的区别
  9. Windows内核函数
  10. 纯CSS实现3D照片墙
  11. cesium three性能比较_硬金和千足金都是黄金,哪个比较好?为什么80%人都说硬金不好?...
  12. vue组件在ios不渲染_VueJS:点击后渲染新组件
  13. 最近给公司撸了一个可视化大屏
  14. 二、JAVA基础、语法
  15. 1、流程控制语句switch 2、数组 3、随机点名器案例
  16. 如何写前端开发的改进建议书?
  17. 如何将pdf批量转换成word?
  18. 苹果CMS对接APP源码NVUE原生渲染
  19. Java数据类型问题
  20. L6 U5 商务方案

热门文章

  1. HTB打靶日记:Acute
  2. 关于useEffect在组件结束销毁时使用记录
  3. 特征工程特征预处理归一化与标准化、鸢尾花种类预测代码实现
  4. 怎么将华为三层交换机配置为DHCP服务器?
  5. 无法卸载mysql server 2008 r2_卸载Microsoft SQL Server 2008 R2 安装程序
  6. 音频中的采样率和比特率的关系
  7. 天下武功出少年:Login 2020的技与道
  8. input的type属性和textarea标签
  9. 重庆计算机学校哪个好考,重庆艺术类院校比较好考的有哪些?
  10. 分治法循环赛c语言,循环赛问题分析和C语言代码-分治法.doc