Echo搜索功能实现:Elasticsearch与Kafka的完美结合
Echo论坛是一个基于SpringBoot+MyBatis+MySQL+Redis+Kafka+Elasticsearch+Spring Security等技术栈构建的开源社区项目,提供了完整的帖子、评论、私信、系统通知、点赞、关注、搜索等功能模块。本文将详细解析Echo论坛中搜索功能的实现原理,重点介绍Elasticsearch与Kafka如何协同工作,为用户提供高效、实时的搜索体验。
搜索功能架构概览
Echo论坛的搜索功能采用了"生产者-消费者"架构模式,通过Kafka实现异步消息传递,结合Elasticsearch的强大全文检索能力,构建了一套高性能的搜索系统。核心实现涉及三个关键组件:
- ElasticsearchService:负责与Elasticsearch交互,处理索引的创建、更新、删除和搜索请求
- EventConsumer:Kafka消息消费者,处理发帖、删帖事件,同步数据到Elasticsearch
- SearchController:接收前端搜索请求,调用ElasticsearchService返回搜索结果
图:Echo论坛使用的Markdown编辑器界面,支持搜索和高亮功能
ElasticsearchService:搜索核心实现
ElasticsearchService是搜索功能的核心服务类,封装了与Elasticsearch的所有交互操作。该类位于src/main/java/com/greate/community/service/ElasticsearchService.java,主要提供了三大功能:
1. 数据同步方法
// 保存帖子到Elasticsearch
public void saveDiscusspost(DiscussPost post) {
discussPostRepository.save(post);
}
// 从Elasticsearch删除帖子
public void deleteDiscusspost(int id) {
discussPostRepository.deleteById(id);
}
这两个方法分别用于将帖子数据同步到Elasticsearch索引和从索引中删除帖子,确保搜索数据与数据库保持一致。
2. 高级搜索实现
searchDiscussPost方法实现了论坛的核心搜索功能,支持多字段搜索、排序和高亮显示:
public Page<DiscussPost> searchDiscussPost(String keyword, int current, int limit) {
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "content"))
.withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
.withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
.withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
.withPageable(PageRequest.of(current, limit))
.withHighlightFields(
new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
).build();
// ...结果处理逻辑
}
该实现具有以下特点:
- 多字段搜索:同时搜索帖子标题和内容
- 多级排序:按帖子类型、得分、创建时间排序,确保优质内容优先展示
- 高亮显示:对匹配的关键词使用
<em>标签高亮,提升用户体验
Kafka消息队列:实现异步数据同步
为了保证搜索数据的实时性和系统的高可用性,Echo论坛使用Kafka实现了数据库与Elasticsearch之间的异步数据同步。相关代码位于src/main/java/com/greate/community/event/EventConsumer.java。
1. 发帖事件处理
当用户发布新帖子时,系统会发送一个TOPIC_PUBLISH事件,由Kafka消费者处理:
@KafkaListener(topics = {TOPIC_PUBLISH})
public void handlePublishMessage(ConsumerRecord record) {
// 解析事件
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
// 获取帖子数据
DiscussPost post = discussPostService.findDiscussPostById(event.getEntityId());
// 同步到Elasticsearch
elasticsearchService.saveDiscusspost(post);
}
2. 删帖事件处理
当帖子被删除时,系统会发送TOPIC_DELETE事件,从Elasticsearch中删除对应索引:
@KafkaListener(topics = {TOPIC_DELETE})
public void handleDeleteMessage(ConsumerRecord record) {
// 解析事件
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
// 从Elasticsearch删除
elasticsearchService.deleteDiscusspost(event.getEntityId());
}
通过Kafka实现异步同步的好处:
- 提高系统响应速度,用户发帖无需等待索引完成
- 解耦业务逻辑,发帖和索引更新独立进行
- 保证数据最终一致性,即使Elasticsearch暂时不可用,也会在恢复后同步数据
SearchController:搜索请求处理
SearchController是搜索功能的入口,负责接收和处理用户的搜索请求,代码位于src/main/java/com/greate/community/controller/SearchController.java。
核心处理流程:
@GetMapping("/search")
public String search(String keyword, Page page, Model model) {
// 调用ElasticsearchService搜索帖子
org.springframework.data.domain.Page<DiscussPost> searchResult =
elasticsearchService.searchDiscussPost(keyword, page.getCurrent()-1, page.getLimit());
// 处理结果,封装用户信息和点赞数
List<Map<String, Object>> discussPosts = new ArrayList<>();
if (searchResult != null) {
for (DiscussPost post : searchResult) {
Map<String, Object> map = new HashMap<>();
map.put("post", post);
map.put("user", userService.findUserById(post.getUserId()));
map.put("likeCount", likeService.findEntityLikeCount(ENTITY_TYPE_POST, post.getId()));
discussPosts.add(map);
}
}
// 传递数据到视图
model.addAttribute("discussPosts", discussPosts);
model.addAttribute("keyword", keyword);
// 设置分页信息
page.setPath("/search?keyword="+ keyword);
page.setRows(searchResult == null ? 0 : (int) searchResult.getTotalElements());
return "/site/search";
}
总结:Echo搜索功能的技术亮点
Echo论坛的搜索功能通过Elasticsearch与Kafka的完美结合,实现了高效、实时、可靠的全文检索服务。主要技术亮点包括:
- 高性能搜索:利用Elasticsearch的倒排索引和相关性评分,提供毫秒级的搜索响应
- 实时数据同步:通过Kafka实现发帖、删帖事件的异步处理,确保搜索结果实时更新
- 用户体验优化:关键词高亮显示、多级排序策略,提升搜索结果的可读性和相关性
- 系统解耦:通过事件驱动架构,将搜索功能与核心业务逻辑解耦,提高系统可维护性
这套搜索解决方案不仅满足了论坛的功能需求,也为其他类似系统提供了可借鉴的实现思路。如果你对Echo项目感兴趣,可以通过以下命令获取源码进行深入学习:
git clone https://gitcode.com/gh_mirrors/echo15/Echo
通过分析Echo论坛的搜索功能实现,我们可以看到如何将Elasticsearch和Kafka这两个强大的工具结合起来,构建一个高效、可靠的搜索系统。这种架构模式不仅适用于论坛项目,也可以广泛应用于各种需要全文检索功能的Web应用中。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



