情况说明
开发牛客社区项目中,原教程视频使用ElasticSearch 6.XX,现需要集成ElasticSearch 7.XX,由于版本变更导致使用差别太大,记录一些自己遇到的问题和解决方案。
使用的Springboot为2.7.4,使用的ElasticSearch版本为7.17.6
问题1
问题:SpringBoot自动注入ElasticsearchTemplate失败。
原因:SpringBoot集成ElasticSearch 7.17中已经弃用ElasticsearchTemplate,只能使用ElasticsearchRestTemplate。
解决方法:将ElasticsearchTemplate修改为ElasticsearchRestTemplate。
问题2
问题:ElasticsearchRepository不再拥有search()方法,只剩下了searchSimilar()方法。
解决方法:没有什么解决方法,不能像教程中那样使用ElasticsearchRepository做复杂的查询了。
问题3
问题:ElasticsearchRestTemplate的使用方法和ElasticsearchTemplate不同,如何使用ElasticsearchRestTemplate实现和教程中一样复杂的查询任务。
解决方法:使用以下代码可以完成和教程中一样的功能,参考自课程评论区。
@Test
public void testSearchByTemplate() {
// 高亮条件
HighlightBuilder highlightBuilder = new HighlightBuilder()
.field("title") // 给哪些自动设置高亮
.field("content")
.requireFieldMatch(false)
.preTags("<em>") // 匹配到的字段间要加的内容
.postTags("</em>"); // 匹配到的字段后要加的内容
// 构建搜索条件
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
.withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC))
.withSorts(SortBuilders.fieldSort("score").order(SortOrder.DESC))
.withSorts(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
.withPageable(PageRequest.of(0, 10))
.withHighlightBuilder(highlightBuilder).build();
SearchHits<DiscussPost> search = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);
SearchPage<DiscussPost> page = SearchHitSupport.searchPageFor(search, searchQuery.getPageable());
System.out.println(page.getTotalElements());
System.out.println(page.getTotalPages());
System.out.println(page.getNumber());
System.out.println(page.getSize());
for (SearchHit<DiscussPost> discussPostSearchHit : page) {
System.out.println(discussPostSearchHit.getHighlightFields()); // 高亮的内容
System.out.println(discussPostSearchHit.getContent()); // 原始的DiscussPost
}
// 将带有高亮内容的DiscussPost封装到page对象中
// 其实可以不封装到 page ,在业务中我们直接用List就可以实现功能。
List<DiscussPost> list = new ArrayList<>();
for (SearchHit<DiscussPost> discussPostSearchHit : page) {
DiscussPost discussPost = discussPostSearchHit.getContent();
if (discussPostSearchHit.getHighlightFields().get("title") != null) {
discussPost.setTitle(discussPostSearchHit.getHighlightFields().get("title").get(0));
}
if (discussPostSearchHit.getHighlightFields().get("content") != null) {
discussPost.setContent(discussPostSearchHit.getHighlightFields().get("content").get(0));
}
list.add(discussPost);
}
Page<DiscussPost> pageInfo = new PageImpl<>(list, searchQuery.getPageable(), search.getTotalHits());
System.out.println(pageInfo.getTotalElements());
System.out.println(pageInfo.getTotalPages());
System.out.println(pageInfo.getNumber());
System.out.println(pageInfo.getSize());
for (DiscussPost discussPost : pageInfo) {
System.out.println(discussPost);
}
}
总的来说,原理和教程中差别不大,代码实现上出现了差别,但是变得更加容易了,理解起来也更加简单,困难点在于api发生了变化。
其他注意点
Springboot 2.7.4集成ElasticSearch 7.17.6
配置文件中不必再写教程中的那些配置了,教程中的已经不推荐使用或者弃用了。
同时也不需要处理Netty冲突的问题了。教程中展现的那些类大部分已经没有了。
并没有系统的学习过ElasticSearch,针对项目中遇到的问题和解决方法做总结,原理上如有不足之处求指教。