文章目录

  • 查询建议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查询建议相关推荐

  1. [ElasticSearch]Suggest查询建议(自动补全纠错)

    1) 概念 查询建议,能够为用户提供良好的使用体验.主要包括:     拼写检查(纠错)     自动建议查询词(自动补全) 2) Suggest种类及参数 2.1 Term Suggester Te ...

  2. Elasticsearch搜索引擎第十一篇-Suggest查询建议

    文章目录 查询建议是什么 ES查询建议API Suggester介绍 term suggester phrase suggester completion suggester 自动补全 查询建议是什么 ...

  3. Java Elastic search 常用查询

    java Elastic 客户端基本使用 引入jar compile 'org.elasticsearch:elasticsearch:5.5.0'compile 'org.elasticsearch ...

  4. java开发中为什么不建议连表查询

    一:单表查询更有利于后续维护 二:代码可复用性高 三:效率问题 a:数据量小的情况下,连表查询的效率还是可以的,但是如果连表比较多,数据量上去,查询是笛卡尔积方式,查询的数据量是成几何倍上升的,这种情 ...

  5. java项目中数据查询慢问题

    1.java代码层面 1)代码块冗余,调用方法过多,能在sql层面解决的问题尽量让sql服务器去解决:比如说查询三个学生的总成绩,有的人会分别去调用三次接口来分别获得三个学生的总成绩,而有的人直接在s ...

  6. ElasticSearch 文档检索、查询建议、数据聚合

    目录 结构化搜索 term 单词匹配(单个值) terms 单词匹配(多个值) range 范围查询 exists 存在查询.miss 缺失查询 ids id匹配 prefix 前缀匹配 wildca ...

  7. 编写高质量代码改善java程序的151个建议——[110-117]异常及Web项目中异常处理

    编写高质量代码改善java程序的151个建议--[110-117]异常及Web项目中异常处理 原创地址:http://www.cnblogs.com/Alandre/(泥沙砖瓦浆木匠),需要转载的,保 ...

  8. Java实现elastic中服务接口性能指标统计(接口QPS、接口99响应时间等)并存入表

    近期需要对线上A服务接口进行健康度监控,即把A服务各个接口每天的性能指标进行统计并写入库表,便于对接口通过周期性数据进行全面分析及接口优化. 据调研了解,有2种解决方案可行: 1)目前服务接口请求信息 ...

  9. 编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议1~5)...

                 The reasonable man adapts himself to the world; The unreasonable one persists in trying ...

最新文章

  1. 如何快捷高效实现仓储精细化、透明化管理?
  2. 【HDU - 1083 】Courses (二分图)
  3. Linux内核深入理解定时器和时间管理(7):相关的系统调用
  4. python课程思维导图_零基础Python学习思维导图,记得收藏
  5. python文件数据类型_python 数据类型 ---文件一
  6. Java后台生成小程序二维码
  7. 学习3 二维游戏动画合成(侠客行)
  8. 高通 MSM8K bootloader 之四: ramdump
  9. 恒讯科技分析:国外服务器中最常用的6种“可视化管理工具”
  10. 2018年最新电子科技大学TCP/IP协议原理(杨宁)CSF视频教程42讲
  11. 运维:你们 JAVA 服务怎么又又又又出问题了,内存降不下来。
  12. SAP中发票校验凭证与取消发票校验凭证的对应关系查询
  13. SpringSecurity 简介
  14. 【C】指针的相关运算练习题
  15. 2023-spring 2.探险营地 — 字符串
  16. oracle number存储小数
  17. B1019(数字黑洞)
  18. vue里面的ref详解
  19. 使用PDFBox合并多个pdf文件
  20. NTLDR is corrupt.The system connot boot

热门文章

  1. android 图片 生成视频,照片制作成视频的方案有吗?如何视频安卓手机视频编辑器将手机里的照片制作成视频...
  2. flex水平垂直居中
  3. PE系统解决:Windows无法更新计算机的启动 0xc000000f
  4. 软工12-13-2 实验报告三——住房贷款计算器所涉及到的数据及计算方法
  5. springboot框架学习 图书管理系统的简单实现
  6. 原油进口将达1.3亿吨 涨价使中国多付百亿美元
  7. Xstart远程连接Linux图形用户界面
  8. Python打包与解压zip
  9. 为c/c++程序设置默认头文件
  10. Vmware Linux虚拟机硬盘扩容