首页 > 其他分享 >自动补全、搜索建议

自动补全、搜索建议

时间:2024-01-10 09:48:56浏览次数:34  
标签:搜索 补全 suggest indexTemplate 自动 commonEntity rData new

作为系统的使用者,我希望用户输入搜索的过程中,系统能进行自动补全和搜索建议,协助用户输入更精准的关键词,提高后续全文搜索阶段文档匹配的准确度。

实现方案

  • 用户刚开始输入的过程中,使用Completion Suggester进行关键词前缀匹配,刚开始匹配项会比较多,随着用户输入字符增多,匹配项越来越少。
  • 如果Completion Suggester已经到了零匹配,可能是用户输入错误,尝试Phrase Suggester进行短语推荐。
  • 如果Phrase Suggester没有找到任何option,开始尝试term Suggester进行单词推荐。
  • 自动补全字段是通过将查询字段分词后,去重,然后加入到suggest字段中。

自动补全

自动补全DSL示例

GET product_completion_index/_search
{
"from": 0,
"size": 100,
"suggest": {
 "czbk-suggest": {
  "prefix": "小米",
  "completion": {
   "field": "searchkey",
   "size": 20,
   "skip_duplicates": true
  }
 }
}
}

自动补全字段数据获取方法

private boolean updateSuggest(HouseIndexTemplate indexTemplate) {
        //将分词字段加入AnalyzeRequestBuilder,通过ik_smart分词后会生成多个词组,然后将词组加入suggest字段
        AnalyzeRequestBuilder requestBuilder = new AnalyzeRequestBuilder(
                this.esClient, AnalyzeAction.INSTANCE, INDEX_NAME, indexTemplate.getTitle(),
                indexTemplate.getLayoutDesc(), indexTemplate.getRoundService(),
                indexTemplate.getDescription(), indexTemplate.getSubwayLineName(),
                indexTemplate.getSubwayStationName());
        //采用ik_smart分词
        requestBuilder.setAnalyzer("ik_smart");
 
        AnalyzeResponse response = requestBuilder.get();
        List<AnalyzeResponse.AnalyzeToken> tokens = response.getTokens();
        if (tokens == null) {
            logger.warn("Can not analyze token for house: " + indexTemplate.getHouseId());
            return false;
        }
 
        List<HouseSuggest> suggests = new ArrayList<>();
        for (AnalyzeResponse.AnalyzeToken token : tokens) {
            // 排序数字类型 & 小于2个字符的分词结果
            if ("<NUM>".equals(token.getType()) || token.getTerm().length() < 2) {
                continue;
            }
 
            HouseSuggest suggest = new HouseSuggest();
            suggest.setInput(token.getTerm());
            suggests.add(suggest);
        }
 
        // 定制化小区自动补全(不需要分词的字段手动额外加入)
        HouseSuggest suggest = new HouseSuggest();
        suggest.setInput(indexTemplate.getDistrict());
        suggests.add(suggest);
 
        indexTemplate.setSuggest(suggests);
        return true;
    }

自动补全代码示例

package com.oldlu.service;
import com.oldlu.commons.pojo.CommonEntity;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import java.util.List;
import java.util.Map;
/**
* @Class: ElasticsearchDocumentService
* @Package com.oldlu.service
* @Description: 文档操作接口
* @Company: http://www.oldlu.com/
*/
public interface ElasticsearchDocumentService {
  //自动补全(完成建议)
  public List<String> cSuggest(CommonEntity commonEntity) throws Exception;
}

Service

/*
  * @Description: 自动补全 根据用户的输入联想到可能的词或者短语
  * @Method: suggester
  * @Param: [commonEntity]
  * @Update:
  * @since: 1.0.0
  * @Return: org.elasticsearch.action.search.SearchResponse
  *
  */
  public List<String> cSuggest(CommonEntity commonEntity) throws Exception {
    //定义返回
    List<String> suggestList = new ArrayList<>();
    //构建查询请求
    SearchRequest searchRequest = new
SearchRequest(commonEntity.getIndexName());
    //通过查询构建器定义评分排序
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
    //构造搜索建议语句,搜索条件字段
    CompletionSuggestionBuilder completionSuggestionBuilder =new
CompletionSuggestionBuilder(commonEntity.getSuggestFileld());
    //搜索关键字
    completionSuggestionBuilder.prefix(commonEntity.getSuggestValue());
    //去除重复
    completionSuggestionBuilder.skipDuplicates(true);
    //匹配数量
    completionSuggestionBuilder.size(commonEntity.getSuggestCount());
    searchSourceBuilder.suggest(new SuggestBuilder().addSuggestion("czbk-
suggest", completionSuggestionBuilder));
    //czbk-suggest为返回的字段,所有返回将在czbk-suggest里面,可写死,sort按照评分排
序
    searchRequest.source(searchSourceBuilder);
    //定义查找响应
    SearchResponse suggestResponse = client.search(searchRequest,
RequestOptions.DEFAULT);
    //定义完成建议对象
    CompletionSuggestion completionSuggestion =
suggestResponse.getSuggest().getSuggestion("czbk-suggest");
    List<CompletionSuggestion.Entry.Option> optionsList =
completionSuggestion.getEntries().get(0).getOptions();
    //从optionsList取出结果
    if (!CollectionUtils.isEmpty(optionsList)) {
      optionsList.forEach(item ->
suggestList.add(item.getText().toString()));
   }
    return suggestList;
 }

Controller

/*
  * @Description 自动补全
  * @Method: suggester
  * @Param: [commonEntity]
  * @Update:
  * @since: 1.0.0
  * @Return: com.oldlu.commons.result.ResponseData
  *
  */
  @GetMapping(value = "/csuggest")
  public ResponseData cSuggest(@RequestBody CommonEntity commonEntity) {
    // 构造返回数据
    ResponseData rData = new ResponseData();
    if (StringUtils.isEmpty(commonEntity.getIndexName()) ||
StringUtils.isEmpty(commonEntity.getSuggestFileld()) ||
StringUtils.isEmpty(commonEntity.getSuggestValue())) {
      rData.setResultEnum(ResultEnum.PARAM_ISNULL);
      return rData;
   }
    //批量查询返回结果
    List<String> result = null;
    try {
      //通过高阶API调用批量新增操作方法
      result = elasticsearchDocumentService.cSuggest(commonEntity);
      //通过类型推断自动装箱(多个参数取交集)
      rData.setResultEnum(result, ResultEnum.SUCCESS, result.size());
      //日志记录
      logger.info(TipsEnum.CSUGGEST_GET_DOC_SUCCESS.getMessage());
   } catch (Exception e) {
      //日志记录
      logger.error(TipsEnum.CSUGGEST_GET_DOC_FAIL.getMessage(), e);
      //构建错误返回信息
      rData.setResultEnum(ResultEnum.ERROR);
   }
    return rData;
 }

拼写纠错

短语推荐DSL示例

GET product_completion_index/_search
{
"suggest": {
 "czbk-suggestion": {
  "text": "adidaas官方旗舰店",
  "phrase": {
   "field": "name",
   "size": 13
  }
 }
}
}

拼写纠错代码示例

Service

/*
  * @Description: 拼写纠错
  * @Method: psuggest
  * @Param: [commonEntity]
  * @Update:
  * @since: 1.0.0
  * @Return: java.util.List<java.lang.String>
  *
  */
  @Override
  public String pSuggest(CommonEntity commonEntity) throws Exception {
    //定义返回
    String pSuggestString = new String();
    //定义查询请求
SearchRequest searchRequest = new
SearchRequest(commonEntity.getIndexName());
    //定义查询条件构建器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //定义排序器
    searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
    //构造短语建议器对象(参数为匹配列)
    PhraseSuggestionBuilder pSuggestionBuilder = new
PhraseSuggestionBuilder(commonEntity.getSuggestFileld());
    //搜索关键字(被纠错的值)
    pSuggestionBuilder.text(commonEntity.getSuggestValue());
    //匹配数量
    pSuggestionBuilder.size(1);
    searchSourceBuilder.suggest(new SuggestBuilder().addSuggestion("czbk-
suggest", pSuggestionBuilder));
    searchRequest.source(searchSourceBuilder);
    //定义查找响应
    SearchResponse suggestResponse = client.search(searchRequest,
RequestOptions.DEFAULT);
    //定义短语建议对象
    PhraseSuggestion phraseSuggestion =
suggestResponse.getSuggest().getSuggestion("czbk-suggest");
    //获取返回数据
    List<PhraseSuggestion.Entry.Option> optionsList =
phraseSuggestion.getEntries().get(0).getOptions();
    //从optionsList取出结果
    if (!CollectionUtils.isEmpty(optionsList)
&&optionsList.get(0).getText()!=null) {
      pSuggestString = optionsList.get(0).getText().string().replaceAll("
","");
   }
    return pSuggestString;
 }

Controller

 
/*
  * @Description: 拼写纠错
  * @Method: suggester2
  * @Param: [commonEntity]
  * @Update:
  * @since: 1.0.0
  * @Return: com.oldlu.commons.result.ResponseData
  *
  */
 @GetMapping(value = "/psuggest")
 public ResponseData pSuggest(@RequestBody CommonEntity commonEntity) {
   // 构造返回数据
   ResponseData rData = new ResponseData();
   if (StringUtils.isEmpty(commonEntity.getIndexName()) ||
StringUtils.isEmpty(commonEntity.getSuggestFileld()) ||
StringUtils.isEmpty(commonEntity.getSuggestValue())) {
     rData.setResultEnum(ResultEnum.PARAM_ISNULL);
     return rData;
}
   //批量查询返回结果
   String result = null;
   try {
     //通过高阶API调用批量新增操作方法
     result = elasticsearchDocumentService.pSuggest(commonEntity);
     //通过类型推断自动装箱(多个参数取交集)
     rData.setResultEnum(result, ResultEnum.SUCCESS, null);
     //日志记录
     logger.info(TipsEnum.PSUGGEST_GET_DOC_SUCCESS.getMessage());
   } catch (Exception e) {
     //日志记录
     logger.error(TipsEnum.PSUGGEST_GET_DOC_FAIL.getMessage(), e);
     //构建错误返回信息
     rData.setResultEnum(ResultEnum.ERROR);
   }
   return rData;
 }

标签:搜索,补全,suggest,indexTemplate,自动,commonEntity,rData,new
From: https://www.cnblogs.com/libin2015/p/17955833

相关文章

  • 软件测试/人工智能/全日制测试开发|利用ChatGPT自动生成自动化测试脚本
    自动化测试是软件测试过程中不可或缺的一部分,它能够提高测试效率,减少测试成本,保障软件质量。然而,编写和维护自动化测试脚本仍然是一个具有挑战性的任务,需要花费大量的时间和精力。学会借助ChatGPT自动生成自动化测试脚本,就可以减少编写自动化脚本的工作量,提高测试效率。如何借助Cha......
  • EasyCVR分组管理新增搜索功能的开发实现
    EasyCVR既具备传统安防视频监控的能力,也具备接入AI智能分析的能力,可拓展性强、视频能力灵活,能对外分发RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、WebRTC等视频流。很多用户在EasyCVR平台中集成了大量的视频,虽然有分组,但体量太大查询起来还是较为麻烦。为了方便用户查找,EasyCVR平......
  • 自动化测试循环控制:学习 ForEach 的精确运用
    在 自动化测试 场景中,当需要对数组内的所有元素分别执行特定操作时,我们通常会采用 ForEach循环 来实现这一过程。例如一个常见的场景:请求一个获取宠物列表的接口,返回了n个宠物的id,然后根据这些宠物id逐一查询并获取每个宠物的详细数据。一般的ForEach循环用JavaScrip......
  • docker 容器cpu限额绑定控制、内存使用、io读写控制及容器停止后自动释放资源
    容器控制cpu使用为避免压力测试时导致虚机爆掉,该测试虚机最好含有四个以上的cpu指定容器可以使用宿主机cpu的份额该参数只对多个容器竞争同一个cpu的时间片时有效参数 -c 或者全称 --cpu-shares可以看到控制cpu的参数使用-c或者全称--cpu-shares[root@localhost~]#......
  • 百度搜索exgraph图执行引擎设计与实践
    作者|搜索Go研发组导读百度搜索exgraph图执行引擎设计重点分成三个部分:图描述语言、图执行引擎、对接扩展。图描述语言是一种基于文本可读的图描述语言,用于描述任务中的算子以及算子之间的依赖关系,即让人可以理解,也可以被计算机理解并执行。图执行引擎是exgraph的核心,负责根据图......
  • spring boot自动装配原理
    学习笔记1@SpringBootConfiguration:该注解上有一个@Configuration注解,表示这个springboot启动类是一个配置类,最终要被注入到spring容器中。   2@EnableAutoConfiguration:表示开启自动配置   3@AutoConfigurationPackage,该注解上有一个@Import(AutoConfigurationPacka......
  • 亚马逊鲲鹏自动测评系统:提升店铺流量与销售的利器
    在跨境电商领域,提升店铺流量、排名以及销售业绩一直是卖家们关注的焦点。近期,亚马逊鲲鹏自动测评系统的推出备受关注,成为卖家们提升竞争力的得力工具。据真实客户反馈,该系统不仅能够全自动化批量操作,而且内置了防指纹技术,通过绑定IP实现每个账号的独立运行,避免了账号关联问题,成为快......
  • 亚马逊鲲鹏自动测评系统:优化店铺运营,提升销售业绩的得力助手
    随着电商竞争日益激烈,卖家们迫切需要能够快速提升店铺流量、排名和销售业绩的工具。近期,亚马逊鲲鹏自动测评系统被认为是一款能够全自动化批量操作的利器。该系统内置防指纹技术,绑定IP后,实现每个账号的独立运行,可快速增加店铺流量,提升排名,从而推动销售业绩的有效工具。使用亚马逊鲲......
  • 亚马逊鲲鹏自动测评系统:优化店铺运营,提升销售业绩的得力助手
    随着电商竞争日益激烈,卖家们迫切需要能够快速提升店铺流量、排名和销售业绩的工具。近期,亚马逊鲲鹏自动测评系统被认为是一款能够全自动化批量操作的利器。该系统内置防指纹技术,绑定IP后,实现每个账号的独立运行,可快速增加店铺流量,提升排名,从而推动销售业绩的有效工具。使用亚马逊鲲......
  • 解决DAYU200自动息屏
    前言方法有两种,一种是通过源码的形式,一种是通过HDC调试工具这里我是用hdc工具完成DAYU200的调试,对于源码编译的形式我没有成功,官方的源码下载后按照官方教程走,他报错,在这上面我花费了几个小时调试,最终放弃。HDC工具简介HDC(HarmonyDeviceConnector)是OpenHarmony为开发人员提供的......