基于SpringBoot整合Elasticsearch实现搜索补全功能
一、概述
想必大家在生活中用过或者体验过这样一种功能,就是搜索智能提示,像百度、淘宝、京东等在搜索内容时,都是有这一功能。今天就是来给大家讲述一下如何简单快速的基于SpringBoot整合ES搜索补全功能~
二、前提
由于SpringBoot和Elasticsearch的版本对应有着严格的要求,故将两者的版本贴一下:
- SpringBoot:2.3.1
- Elasticsearch: 7.6.2
三、实现过程
如果事先有了解过的同学肯定知道,在SpringBoot容器启动时,会默认初始化标有 @Document 注解的类,若ES中未创建索引,则会以 @Document 中的 indexName 为索引名创建索引,若ES中已存在该索引,则会忽略。在这里先贴一下ES实体类
@Data
@Document(indexName = "es_test", type = "_doc", shards = 1, replicas = 0)
@NoArgsConstructor
@AllArgsConstructor
public class EsTest{
@Id
@Field(type = FieldType.Keyword)
private String id;
@Field(analyzer = "standard", type = FieldType.Text)
private String name;
@Field(type = FieldType.Integer)
private Integer age;
@CompletionField(analyzer="ik_smart",searchAnalyzer="ik_smart", maxInputLength = 100)
private Completion suggest;
public EsTest(String id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
接着就是进行测试咯,这里我是使用的SpringBoot测试类进行测试
首先就是得先将数据插入ES中,这里我写了个EsTestRepository继承了ElasticsearchRepository,可以很方便的调用一些API(具体有哪些API就不在这赘述咯~)
/**
* @author Brave
* @version V1.0
* @date 2020/11/16
*/
public interface EsTestRepository extends ElasticsearchRepository<Student, String> {
}
接着就是编写测试类,其中test01方法呢,就是将数据插入至ES中,来方便后面实现搜索补全功能
/**
* @author Brave
* @version V1.0
* @date 2021/3/12
*/
@RunWith(SpringRunner.class)
@SpringBootTest
class SearchTestApplication {
@Autowired
private EsTestRepository esTestRepository;
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
private ElasticsearchOperations elasticsearchOperations;
@Test
void test01(){
List<EsTest> esTests = Lists.newArrayList();
EsTest esTest01 = new EsTest("1","中华人民共和国",18);
List<String> suggestList = new ArrayList<>();
suggestList.add("中华人民共和国");
esTest01.setSuggest(new Completion(suggestList.toArray(new String[suggestList.size()])));
esTests.add(esTest01);
EsTest esTest02 = new EsTest("2","中国人民大会堂",19);
List<String> suggestList01 = new ArrayList<>();
suggestList01.add("中国人民大会堂");
esTest02.setSuggest(new Completion(suggestList01.toArray(new String[suggestList01.size()])));
esTests.add(esTest02);
EsTest esTest03 = new EsTest("3","中国人民一家亲",20);
List<String> suggestList02 = new ArrayList<>();
suggestList02.add("中国人民一家亲");
esTest03.setSuggest(new Completion(suggestList02.toArray(new String[suggestList02.size()])));
esTests.add(esTest03);
EsTest esTest04 = new EsTest("4","中国南波万",21);
List<String> suggestList03 = new ArrayList<>();
suggestList03.add("中国南波万");
esTest04.setSuggest(new Completion(suggestList03.toArray(new String[suggestList03.size()])));
esTests.add(esTest04);
esTestRepository.saveAll(esTests);
}
}
重头戏来咯!!
@Test
void test02(){
// 使用suggest进行标题联想
CompletionSuggestionBuilder suggest = SuggestBuilders.completionSuggestion("suggest")
// 关键字(参数传此)
.prefix(keyword)
// 重复过滤
.skipDuplicates(true)
// 匹配数量
.size(10);
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("my-suggest",suggest);
IndexCoordinates indexCoordinates = elasticsearchOperations.getIndexCoordinatesFor(EsTest.class);
// 查询
SearchResponse goodsNameSuggestResp = elasticsearchRestTemplate.suggest(suggestBuilder, indexCoordinates);
Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> goodsNameSuggest = goodsNameSuggestResp
.getSuggest().getSuggestion("my-suggest");
// 处理返回
List<String> suggests = goodsNameSuggest.getEntries().stream().map(x -> x.getOptions().stream().map(y->y.getText().toString()).collect(Collectors.toList())).findFirst().get();
// 输出内容
for (String suggest : suggests) {
System.out.println("suggest = " + suggest);
}
上面test02()这个方法就是实现搜索补全的代码啦!
四、结尾
如此高大上的功能就这样实现咯,当然其中也有许多可以优化的地方,例如为ES上安装ik分词器以及拼音分词器,这样子补全功能又会更加人性化!有兴趣的小伙伴们快去试试吧!若有啥不足的地方也欢迎大家点评我将热情回复😉

浙公网安备 33010602011771号