1、功能需求
根据微信备注、昵称、微信号、来搜索好友、单聊
根据群聊名称搜索群聊
能根据汉语拼音,汉语拼音前缀来进行搜索
2、优化前:走的ES模糊搜索,性能差,请求慢
3、优化后:使用分词器,利用ES倒排索引特性,加快查询速度
4、优化方案如下:使用standard分词器,结合ES的minimum_should_match特性
理由一:传统的中文分词器IK,拼音分词器,并不能很好适合天权“微信搜索”的需求场景、比如,姓名,昵称,微信号、备注,往往并不是生活中的常用词汇,且文本短。
理由二:可根据线上使用情况,动态的调整搜索结果的相关度(设置minimum_should_match百分比)
理由三:standard是一个英文分词器,对于所有的中文字符,会对每个中文字符进行分词的特点。此特性,结合minimum_should_match拥有良好的实战效果。虽然ik_max_word拥有对中文语句的分词细致化的良好效果,但是远远不如standard,对每个中文字符进行分词来的细致
/**
- 用 standard 分词器 细分 中文词语,解决分词不够细致的问题
*/
@ESMapping(datatype = DataType.text_type, analyzer = Analyzer.standard, search_analyzer = Analyzer.standard)
private String assist;
用例一:设置 minshouldmatch = 80%,搜索关键字 key = “刘德华的”,存储ES doc文档 assist = “刘德华 川 105期数学 horken_kason liudehua liude liu ldh ld l”。
搜索底层步骤:
第一步:对key进行分词,使用standard分词器。分词后的词汇为:“刘” “德” “华” “的” , 4个词
第二步:4 个term查找 { "term": { "body": "刘"}} ... 结果 3 个命中,“刘” “德” “华” 命中,“的”字没有命中
' 第三步:4个term最少需要命中80%,4 * 0.8 = 3.2 向下取整为 3
第四步:判断必须命中数和已经命中数的大小 3 >= 3,所以这条doc作为搜索结果
用例二:设置 minshouldmatch = 80%,搜索关键字 key = “刘啦德的华”,ES的文档里 assist = “刘德华 川 105期数学 horken_kason liudehua liude liu ldh ld l”。
搜索底层步骤:
第一步:对key进行分词,使用standard分词器。分词后的词汇为:“刘” “啦” “德” “的” “华” ,5个词
第二步:5个term 查找{ "term": { "body": "刘"}} ...,只有3个命中,“刘” “德” “华” 命中
第三步:5个term最少需要命中80%,5 * 0.8 = 4 向下取整为 4
第四步:3 < 4,这条doc不能作为搜索的结果
5、效果如下
评论区