1、题记
题出有因:
有位医生朋友在QQ留言,说对于专业词汇,检索不到怎么办?
举例:搜索:痉湿暍病 结合了国内的多款分词插件,竟然搜索不到?
2、共性认知
2.1 为什么需要分词?
wildcard模糊匹配不也可以全字段模糊查询,进而得到结果呢?
但是,当文档结果集非常大,模糊匹配必然会有性能问题。
搜索引擎的为什么能快速检索到自己查询的关键字呢?倒排索引是以 O(1)
时间复杂度,一招解决问题的关键。
没有词语,怎么建立索引呢?于是,我们需要中文分词!
并且分词发生在用户 查询
和 服务器建立索引
时。
2.2 查全率 VS 查准率
查全率
=(检索出的相关信息量/系统中的相关信息总量) 100%
查准率
=(检索出的相关信息量/检索出的信息总量) 100%
前者是衡量检索系统和检索者检出相关信息的能力,后者是衡量检索系统和检索者拒绝非相关信息的能力。两者合起来,即表示检索效率。
3、Elasticsearch 多种检索类型选型指南
3.1 match检索
含义:精细化切词匹配,只要待匹配的语句中,有一个满足检索结果,就能匹配到。
场景:结果可能达不到实际开发预期。实际业务中但凡有精准度要求的都较少或几乎不使用。
举例:
1PUT doctor_index/_doc/4 2{ 3 "content":"刘强东方才只是睡觉了,并没有违法" 4}
我输入检索词
“小王睡觉”
,也能匹配到上面的content。
3.2match_phrase:短语匹配
含义:相比match,更强调多个分词结果和顺序,都要完整匹配才能检索到。
场景:实战应用中会
较多使用
,结合slop调整顺序和精度。
3.3 query_string
含义:支持 与(AND)、或(OR)、非(NOT)
的匹配。
场景:有与或非多值匹配的场景,无需单独再开发,开箱即用。底层的关键词实际走的是match_phrase,
不过多个参数(如:default_operator,phrase_slop等)可控制调整精度。
举例:
1GET /_search 2{ 3 "query": { 4 "query_string" : { 5 "default_field" : "content", 6 "query" : "刘强东 AND 无罪" 7 } 8 } 9}
4、为什么会检索不到?
结合几个典型例子,实践分析一把。
4.1 分词原因/词典未收录原因
举例:
1PUT doctor_index/_doc/3 2{ 3 "content":"佟大为老婆生了孩子" 4} 5POST doctor_index/_search 6{ 7"profile":"true", 8 "query": { 9 "match_phrase": { 10 "content": "佟大" 11 } 12 } 13}
包含”佟大”,但是短语匹配搜索不到。
原因分析:
来看看切词,
1GET /_analyze 2{ 3 "text":"佟大为老婆生了孩子", 4 "analyzer": "ik_max_word" 5}
token | start_offset | end_offset | position |
佟大为 |
0 |
3 |
0 |
大为 |
1 |
3 |
1 |
大 |
1 |
2 |
2 |
为 |
2 |
3 |
3 |
老婆 |
3 |
5 |
4 |
老 |
3 |
4 |
5 |
婆 |
4 |
5 |
6 |
生了 |
5 |
7 |
7 |
生 |
5 |
6 |
8 |
了 |
6 |
7 |
9 |
孩子 |
7 |
9 |
10 |
搜索:佟大,如果执意也要搜出结果呢?
token | start_offset | end_offset | position |
佟 |
0 |
1 |
0 |
大 |
1 |
2 |
1 |
分析可知:佟大两个字组成的连词,没有作为词组分配的,所以匹配不到。
4.2 postition位置不一致。
假定我字典里面没有收录“刘强东”这个人名。
举例:
1PUT doctor_index/_doc/4 2{ 3 "content":"刘强东方才只是睡觉了,并没有违法" 4} 5POST doctor_index/_search 6{ 7 "query": { 8 "match_phrase": { 9 "content": "刘强东" 10 } 11 } 12}
原因分析:
token | position |
刘强 |
0 |
东方 |
1 |
方才 |
2 |
方 |
3 |
才 |
4 |
只是 |
5 |
睡觉 |
6 |
睡 |
7 |
觉了 |
8 |
觉 |
9 |
了 |
10 |
并没有 |
11 |
并没 |
12 |
并 |
13 |
没有 |
14 |
有 |
15 |
违法 |
16 |
法 |
17 |
而刘强东的分词结果是:
token | position |
刘强 |
0 |
东 |
1 |
match_phrase匹配必须:
position一致,可以上下对比一下,由于东方组成了短语,导致结果position不一致,匹配结果检索不到。
5、如何让存在的字符都能搜索到呢?
5.1 关于match_phrase的精确度问题
方案一:match_phrase_prefix结合slop的方案
但是,事后分析发现:slop设置不论多大、多小,都可能会引入噪音数据,导致结果 不准确
。
方案二:match_phrase结合match should关联匹配。
缺点:依然会引入噪音数据。
5.2 参考阿里云的实践思路,采取:逐个字分词和ik分词结合的方式。
单字分词应用场景——对于像姓名类字段,业务上需要支持完整匹配,又需要支持单字查询。可以配置1个keyword字段(不分词);
1个text字段(分词),分词器选择Elasticsearch 默认分词器standard
,按单个汉字切分。
5.3 实践一把
我们处理问题的前提:提升查全率。
1PUT mx_index 2{ 3 "mappings": { 4 "_doc": { 5 "properties": { 6 "content": { 7 "type": "text", 8 "analyzer": "ik_max_word", 9 "fields": { 10 "standard": { 11 "type": "text", 12 "analyzer": "standard" 13 }, 14 "keyword": { 15 "type": "keyword", 16 "ignore_above": 256 17 } 18 } 19 } 20 } 21 } 22 } 23} 24 25PUT mx_index/_doc/1 26{ 27 "content":"佟大为老婆生了孩子" 28} 29 30POST mx_index/_search 31{ 32 "query": { 33 "bool": { 34 "should": [ 35 { 36 "match_phrase": { 37 "content": "佟大" 38 } 39 }, 40 { 41 "match_phrase": { 42 "content.standard": "佟大" 43 } 44 } 45 ] 46 } 47 } 48}
6、小结
不是放之四海而皆准的实现方式。要看你的系统对查全率和查准率的要求了,正常的业务场景:
-
1)
动态更新词库、词典
; -
2)match_phrase结合slop就能解决问题。
结合自己的业务场景
。
相信这么处理,开头医生的需求也能实现了。
加入知识星球,更短时间更快习得更多干货!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- cocosdx接bugly,上传符号表,有一部分内容解析出来了, 另一部分没有解析出来
- 培训班出来的怎么了?
- SamSam作者又出来浪了
- MyBatis 的插件对象如何创建出来的
- Vue项目build后,图片加载不出来
- 培训出来的程序员容易被代替吗?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法笔记上机训练实战指南
胡凡、曾磊 / 机械工业出版社 / 2016-7 / 57
《算法笔记上机训练实战指南》是《算法笔记》的配套习题集,内容按照《算法笔记》的章节顺序进行编排,其中整理归类了PAT甲级、乙级共150多道题的详细题解,大部分题解均编有题意、样例解释、思路、注意点、参考代码,且代码中包含了详细的注释。读者可以通过本书对《算法笔记》的知识点进行更深入的学习和理解。书中印有大量二维码,用以实时更新或补充书籍的内容及发布本书的勘误。 《算法笔记上机训练实战指南》可......一起来看看 《算法笔记上机训练实战指南》 这本书的介绍吧!