系列文章索引
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