[Java]-Elastic中suggest查询建议
文章目录
- 查询建议API
- 单个建议查询词
- 多个建议查询词
- Suggester
- Term suggester
- 参数
- phrase suggester
- completion suggester
- 搜索框实现
查询建议(suggest)是为用户提供良好的使用体验。主要包括: 拼写检查; 自动建议查询词(自动补全)。
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-suggesters.html#。
查询建议API
查询建议也是使用_search端点地址。在DSL中suggest节点来定义需要的建议查询。
单个建议查询词
POST _search
{"query" : {"match": {"message": "tring out Elasticsearch"}},"suggest" : { <!-- 定义建议查询 -->"my-suggestion" : { <!-- 一个建议查询名 -->"text" : "tring out Elasticsearch", <!-- 查询文本 -->"term" : { <!-- 使用词项建议器 -->"field" : "message" <!-- 指定在哪个字段上获取建议词 -->}}}
}
多个建议查询词
可以多个建议词一起查询:
POST _search
{"suggest": {"my-suggest-1" : {"text" : "tring out Elasticsearch","term" : {"suggest_mode": "missing", "field" : "message"}},"my-suggest-2" : {"text" : "kmichy","term" : {"field" : "user"}}}
}
也可以多个查询使用同一个查询文本:
POST _search
{"suggest": {"text" : "tring out Elasticsearch","my-suggest-1" : {"term" : {"field" : "message"}},"my-suggest-2" : {"term" : {"field" : "user"}}}
}
Suggester
Suggesters基本的运作原理是将输入的文本分解为token,然后在索引的字典里查找相似的term并返回。 根据使用场景的不同,Elasticsearch里设计了4种类别的Suggester,分别是:
- Term Suggester
- Phrase Suggester
- Completion Suggester
- Context Suggester
Term suggester
对输入的文本进行分词,为每个词进行模糊匹配查询提供词项建议。对于在索引中存在词默认不提供建议词,不存在的词则根据模糊查询结果进行排序后取一定数量的建议词。
项名 | 说明 |
---|---|
text | 输入文本(用户的输入),根据此文本查找建议 |
field | 要查询的字段 |
analyzer | 指定分词器 |
size | 每个词返回的最大建议词数量 |
sort |
建议词的排序方式: 1. score:先按评分排序,再按文档频率、term顺序排; 2. frequency:先按文档频率排序,再按评分、term顺序排 |
suggest_mode |
建议模式(控制提供建议词的方式): 1. missing:默认方式,仅在‘要搜索词项’不在索引中存在时,才提供建议词; 2. popular:仅提供频率比‘要搜索词项’高的建议词; 3. always:总是提供建议词; |
public void termSuggestSearch(String index, String field, String keyword) {try (RestHighLevelClient rhlClient = ESClient.getClient()) {TermSuggestionBuilder termSuggestion = SuggestBuilders.termSuggestion(field);termSuggestion.text(keyword);termSuggestion.size(5);termSuggestion.suggestMode(TermSuggestionBuilder.SuggestMode.ALWAYS);SuggestBuilder suggestBuilder = new SuggestBuilder();String suggestName = "sugName";suggestBuilder.addSuggestion(suggestName, termSuggestion);SearchRequest searchRequest = new SearchRequest(index);SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();sourceBuilder.suggest(suggestBuilder);searchRequest.source(sourceBuilder);SearchResponse response = rhlClient.search(searchRequest, RequestOptions.DEFAULT);Suggest suggest = response.getSuggest();if (suggest != null) {Suggest.Suggestion result = suggest.getSuggestion(suggestName);for (Object term : result.getEntries()) {if(term instanceof TermSuggestion.Entry) {TermSuggestion.Entry entry = (TermSuggestion.Entry)term;entry.getOptions().forEach(z->{System.out.println("Text: " + z.getText() + ", freq: " + z.getFreq() + ", score: " + z.getScore());});}else {System.out.println("It is not termSuggestion.Entry: " + term);}}}} catch (Exception ex) {System.out.println(index + " query fail: " + ex);}
}
参数
字段名称 | 说明 |
---|---|
max_edits
|
表示被选为建议的edit distance 的最大值,只能是1,2之间的数(可以是小数),默认是2
|
prefix_length
|
表示被选为建议的最小前缀字符的长度,默认为1 ,增加这个长度可以提高拼写检查的性能,通常拼写错误不会发生在术语的最前面
|
min_word_length
|
表示推荐文本的最小长度,默认为4 |
shard_size
|
设置从每个分片检索的建议的最大数量。在reduce阶段,根据size选项只返回前N个建议。默认是和size选项一样 |
max_inspections
|
表示一个因子,这个参数和shard_size参数相乘以便在分片级别检查更多的候选者的拼写错误,参数默认为5 |
min_doc_freq
|
表示一个建议中应包含文档数目的最小限制,可以指定为一个确切的数或文档数的相对百分比,默认是0(即不开启此功能) |
max_term_freq
|
表示推荐文本可以包含的文档数目的最大限制,可以是一个代表文档频率的确切值,也可以是一个相对百分数(比如0.4),默认是0.01f。这个参数可以用来排除高频术语的拼写检查 |
string_distance
|
表示一个字符串距离用于和推荐内容相比它们之间的相似性,这个参数可能的值有5个:internal :表示默认的基于damerau_levenshtein 算法,但在比较字符串距离内的索引已经做过高度优化damerau_levenshtein :是一种基于Damerau-Levenshtein 算法的字符串距离算法levenshtein :是一种基于Levenshtein edit distance算法的字符串距离算法jaro_winkler :是一种基于Jaro-Winkler 算法的字符串距离算法ngram :是一种基于字符连词的字符串距离算法
|
phrase suggester
短语建议,在term的基础上,考量多个term间的关系(是否同时出现在索引的原文里,相邻程度,以及词频等):
public void phraseSuggestSearch(String index, String field, String keyword) {try (RestHighLevelClient rhlClient = ESClient.getClient()) {PhraseSuggestionBuilder phraseSuggestion = SuggestBuilders.phraseSuggestion(field);phraseSuggestion.text(keyword);phraseSuggestion.size(5);SuggestBuilder suggestBuilder = new SuggestBuilder();String suggestName = "sugName";suggestBuilder.addSuggestion(suggestName, phraseSuggestion);SearchRequest searchRequest = new SearchRequest(index);SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();sourceBuilder.suggest(suggestBuilder);searchRequest.source(sourceBuilder);SearchResponse response = rhlClient.search(searchRequest, RequestOptions.DEFAULT);Suggest suggest = response.getSuggest();if (suggest != null) {Suggest.Suggestion result = suggest.getSuggestion(suggestName);for (Object term : result.getEntries()) {if(term instanceof PhraseSuggestion.Entry) {PhraseSuggestion.Entry entry = (PhraseSuggestion.Entry)term;entry.getOptions().forEach(z->{System.out.println("Text: " + z.getText() + ", score: " + z.getScore());});}else {System.out.println("It is not phraseSuggestion.Entry: " + term);}}}} catch (Exception ex) {System.out.println(index + " query fail: " + ex);}
}
completion suggester
Completion Suggester提供自动完成/随类型搜索的功能;这是一种导航特性,可以在用户键入时引导他们找到相关结果,提高搜索精度。因此实现上它和前面两个Suggester采用了不同的数据结构,索引并非通过倒排来完成,而是将analyze过的数据编码成FST和索引一起存放。对于一个open状态的索引,FST会被ES整个装载到内存里的,进行前缀查找速度极快。但是FST只能用于前缀查找,这也是Completion Suggester的局限所在。
为了使用自动补全,索引中用来提供补全建议的字段需特殊设计,字段类型为 completion。
搜索框实现
要实现搜索框的补全/纠错功能:
- 在用户刚开始输入的过程中,使用Completion Suggester进行关键词前缀匹配,刚开始匹配项会比较多,随着用户输入字符增多,匹配项越来越少。
- 如果用户输入比较精准,可能Completion Suggester的结果已经够好,用户已经可以看到理想的备选项了。 如果Completion Suggester已经到了零匹配,那么可以猜测是否用户有输入错误,这时候可以尝试一下Phrase Suggester。如果Phrase Suggester没有找到任何option,开始尝试term Suggester。
- 精准程度上(Precision)看: Completion > Phrase > term, 而召回率上(Recall)则反之。从性能上看,Completion Suggester是最快的,如果能满足业务需求,只用Completion Suggester做前缀匹配是最理想的。Phrase和Term由于是做倒排索引的搜索,相比较而言性能应该要低不少,应尽量控制suggester用到的索引的数据量,最理想的状况是经过一定时间预热后,索引可以全量map到内存。
[Java]-Elastic中suggest查询建议相关推荐
- [ElasticSearch]Suggest查询建议(自动补全纠错)
1) 概念 查询建议,能够为用户提供良好的使用体验.主要包括: 拼写检查(纠错) 自动建议查询词(自动补全) 2) Suggest种类及参数 2.1 Term Suggester Te ...
- Elasticsearch搜索引擎第十一篇-Suggest查询建议
文章目录 查询建议是什么 ES查询建议API Suggester介绍 term suggester phrase suggester completion suggester 自动补全 查询建议是什么 ...
- Java Elastic search 常用查询
java Elastic 客户端基本使用 引入jar compile 'org.elasticsearch:elasticsearch:5.5.0'compile 'org.elasticsearch ...
- java开发中为什么不建议连表查询
一:单表查询更有利于后续维护 二:代码可复用性高 三:效率问题 a:数据量小的情况下,连表查询的效率还是可以的,但是如果连表比较多,数据量上去,查询是笛卡尔积方式,查询的数据量是成几何倍上升的,这种情 ...
- java项目中数据查询慢问题
1.java代码层面 1)代码块冗余,调用方法过多,能在sql层面解决的问题尽量让sql服务器去解决:比如说查询三个学生的总成绩,有的人会分别去调用三次接口来分别获得三个学生的总成绩,而有的人直接在s ...
- ElasticSearch 文档检索、查询建议、数据聚合
目录 结构化搜索 term 单词匹配(单个值) terms 单词匹配(多个值) range 范围查询 exists 存在查询.miss 缺失查询 ids id匹配 prefix 前缀匹配 wildca ...
- 编写高质量代码改善java程序的151个建议——[110-117]异常及Web项目中异常处理
编写高质量代码改善java程序的151个建议--[110-117]异常及Web项目中异常处理 原创地址:http://www.cnblogs.com/Alandre/(泥沙砖瓦浆木匠),需要转载的,保 ...
- Java实现elastic中服务接口性能指标统计(接口QPS、接口99响应时间等)并存入表
近期需要对线上A服务接口进行健康度监控,即把A服务各个接口每天的性能指标进行统计并写入库表,便于对接口通过周期性数据进行全面分析及接口优化. 据调研了解,有2种解决方案可行: 1)目前服务接口请求信息 ...
- 编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议1~5)...
The reasonable man adapts himself to the world; The unreasonable one persists in trying ...
最新文章
- 如何快捷高效实现仓储精细化、透明化管理?
- 【HDU - 1083 】Courses (二分图)
- Linux内核深入理解定时器和时间管理(7):相关的系统调用
- python课程思维导图_零基础Python学习思维导图,记得收藏
- python文件数据类型_python 数据类型 ---文件一
- Java后台生成小程序二维码
- 学习3 二维游戏动画合成(侠客行)
- 高通 MSM8K bootloader 之四: ramdump
- 恒讯科技分析:国外服务器中最常用的6种“可视化管理工具”
- 2018年最新电子科技大学TCP/IP协议原理(杨宁)CSF视频教程42讲
- 运维:你们 JAVA 服务怎么又又又又出问题了,内存降不下来。
- SAP中发票校验凭证与取消发票校验凭证的对应关系查询
- SpringSecurity 简介
- 【C】指针的相关运算练习题
- 2023-spring 2.探险营地 — 字符串
- oracle number存储小数
- B1019(数字黑洞)
- vue里面的ref详解
- 使用PDFBox合并多个pdf文件
- NTLDR is corrupt.The system connot boot
热门文章
- android 图片 生成视频,照片制作成视频的方案有吗?如何视频安卓手机视频编辑器将手机里的照片制作成视频...
- flex水平垂直居中
- PE系统解决:Windows无法更新计算机的启动 0xc000000f
- 软工12-13-2 实验报告三——住房贷款计算器所涉及到的数据及计算方法
- springboot框架学习 图书管理系统的简单实现
- 原油进口将达1.3亿吨 涨价使中国多付百亿美元
- Xstart远程连接Linux图形用户界面
- Python打包与解压zip
- 为c/c++程序设置默认头文件
- Vmware Linux虚拟机硬盘扩容