Elasticsearch实战(三):Springboot实现Elasticsearch搜索推荐

系列文章索引

Elasticsearch实战(一):Springboot实现Elasticsearch统一检索功能
Elasticsearch实战(二):Springboot实现Elasticsearch自动汉字、拼音补全,Springboot实现自动拼写纠错
Elasticsearch实战(三):Springboot实现Elasticsearch搜索推荐
Elasticsearch实战(四):Springboot实现Elasticsearch指标聚合与下钻分析
Elasticsearch实战(五):Springboot实现Elasticsearch电商平台日志埋点与搜索热词

一、什么是搜索推荐

例如:关键词输入【阿迪达斯 耐克 外套 运动鞋 袜子】

汪~没有找到与“阿迪达斯 耐克 外套 运动鞋 袜子”相关的商品,为您推荐“ 阿迪达斯耐克运动鞋”的相关商品,或者试试:
在这里插入图片描述

二、新增测试数据

/*
 * @Description: 批量新增文档,可自动创建索引、自动创建映射
 * @Method: bulkAddDoc
 * @Param: [indexName, map]
 *
 */
public static RestStatus bulkAddDoc(CommonEntity commonEntity) throws Exception {
    
    
    //通过索引构建批量请求对象
    BulkRequest bulkRequest = new BulkRequest(commonEntity.getIndexName());
    //循环前台list文档数据
    for (int i = 0; i < commonEntity.getList().size(); i++) {
    
    
        bulkRequest.add(new IndexRequest().source(XContentType.JSON, SearchTools.mapToObjectGroup(commonEntity.getList().get(i))));
    }
    //执行批量新增
    BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
    return bulkResponse.status();
}

public static void main(String[] args) throws Exception {
    
    
    // 批量插入
    CommonEntity commonEntity = new CommonEntity();
    commonEntity.setIndexName("product_completion_index"); // 索引名
    List<Map<String, Object>> list = new ArrayList<>();
    commonEntity.setList(list);
    list.add(new CommonMap<String, Object>().putData("searchkey", "阿迪达斯袜子").putData("name", "阿迪达斯袜子"));
    list.add(new CommonMap<String, Object>().putData("searchkey", "阿迪达斯外套").putData("name", "阿迪达斯外套"));
    list.add(new CommonMap<String, Object>().putData("searchkey", "阿迪达斯运动鞋").putData("name", "阿迪达斯运动鞋"));
    list.add(new CommonMap<String, Object>().putData("searchkey", "耐克运动鞋").putData("name", "耐克运动鞋"));
    bulkAddDoc(commonEntity);
}

查询:

GET product_completion_index/_search
{
    
    
    "suggest": {
    
    
        "czbk-suggestion": {
    
    
            "text": "阿迪达斯 耐克 外套 运动鞋 袜子",
            "term": {
    
    
                "field": "name",
                "min_word_length": 2,
                "string_distance": "ngram",
                "analyzer": "ik_smart"
            }
        }
    }
}

在这里插入图片描述

三、搜索推荐的实现

1、es官网

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-suggesters.html#term-suggester

在这里插入图片描述
在这里插入图片描述

2、Java实现搜索推荐

定义分词器:analyzer(“ik_smart”)
定义算法:.stringDistance(TermSuggestionBuilder.StringDistanceImpl.NGRAM);

/*
 * @Description: 自动补全 根据用户的输入联想到可能的词或者短语
 * @Method: suggester
 * @Param: [commonEntity]
 * @Update:
 * @since: 1.0.0
 * @Return: org.elasticsearch.action.search.SearchResponse
 * >>>>>>>>>>>>编写思路简短总结>>>>>>>>>>>>>
 * 1、定义远程查询
 * 2、定义查询请求(评分排序)
 * 3、定义自动完成构建器(设置前台建议参数)
 * 4、将自动完成构建器加入到查询构建器
 * 5、将查询构建器加入到查询请求
 * 6、获取自动建议的值(数据结构处理)
 */
public static String tSuggest(CommonEntity commonEntity) throws Exception {
    
    
    //定义返回
    String tSuggestString = new String();
    //定义查询请求
    SearchRequest  searchRequest=new SearchRequest(commonEntity.getIndexName());
    //定义查询构建器
    SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
    searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));

    //构造词条建议语句,搜索条件字段
//        TermSuggestionBuilder termSuggestiontextBuilder = SuggestBuilders.termSuggestion(commonEntity.getSuggestFileld());
    TermSuggestionBuilder termSuggestiontextBuilder=new TermSuggestionBuilder(commonEntity.getSuggestFileld());
    //搜索关键字
    termSuggestiontextBuilder.text(commonEntity.getSuggestValue());
    //输入的建议词分词
    termSuggestiontextBuilder.analyzer("ik_smart");
    //建议文本术语必须包含的最小长度。默认值为4。(旧名称“ min_word_len”已弃用)
    termSuggestiontextBuilder.minWordLength(2);
    //用于比较建议术语的相似程度的字符串距离实现
    termSuggestiontextBuilder.stringDistance(TermSuggestionBuilder.StringDistanceImpl.NGRAM);
    //将词条建议器加入到查询构建器中
    searchSourceBuilder.suggest(new SuggestBuilder().addSuggestion("common-suggest",termSuggestiontextBuilder));
    //将查询构建器加入到查询请求中
    searchRequest.source(searchSourceBuilder);
    //定义查找响应
    SearchResponse suggestResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    //定义完成建议对象
    TermSuggestion termSuggestion = suggestResponse.getSuggest().getSuggestion("common-suggest");
    //获取返回数据
    List<TermSuggestion.Entry.Option> optionsList = termSuggestion.getEntries().get(0).getOptions();
    //从optionsList取出结果
    if (!CollectionUtils.isEmpty(optionsList) && optionsList.get(0).getText()!=null) {
    
    
        tSuggestString = optionsList.get(0).getText().toString();
    }
    return tSuggestString;
}
public static void main(String[] args) throws Exception {
    
    
    CommonEntity suggestEntity = new CommonEntity();
    suggestEntity.setIndexName("product_completion_index"); // 索引名
    suggestEntity.setSuggestFileld("name"); // 自动补全查找列
    suggestEntity.setSuggestValue("阿迪达斯 耐克 外套 运动鞋 袜子"); //  自动补全输入的关键字
    System.out.println(tSuggest(suggestEntity)); // 结果:阿迪达斯外套
}

3、总结

1、min_word_length,建议文本术语必须包含的最小长度。默认值为4。切记!
2、string_distance,用于比较建议术语的相似程度的字符串距离实现,使用ngram

猜你喜欢

转载自blog.csdn.net/A_art_xiang/article/details/132260902