第6章 Elasticsearch,分布式搜索引擎【仿牛客网社区论坛项目】
- 前言
- 推荐
- 项目总结
- 第6章 Elasticsearch,分布式搜索引擎
- 1.Elasticsearch入门
- 2.Spring整合Elasticsearch
- DiscussPostRepository
- DiscussPostController
- EventConsumer
- 3.开发社区搜索功能
- 最后
前言
2023-4-30 20:42:51
推荐
仿牛客网项目【面试】
项目总结
第6章 Elasticsearch,分布式搜索引擎
1.Elasticsearch入门
2.Spring整合Elasticsearch
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
DiscussPostRepository
package com.jsss.community.dao.elasticsearch;
import com.jsss.community.entity.DiscussPost;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/*
ElasticsearchRepository<DiscussPost, Integer>
DiscussPost:接口要处理的实体类
Integer:实体类中的主键是什么类型
ElasticsearchRepository:父接口,其中已经事先定义好了对es服务器访问的增删改查各种方法。Spring会给它自动做一个实现,我们直接去调就可以了。
*/
@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {
}
DiscussPostController
发帖|删帖的时候,放到kakfa中了
@RequestMapping(path = "/add",method = RequestMethod.POST)
@ResponseBody
public String addDiscussPost(String title,String content){
User user=hostHolder.getUser();
if (user==null){
return CommunityUtil.getJSONString(403,"你还没有登录");
}
DiscussPost post=new DiscussPost();
post.setUserId(user.getId());
post.setTitle(title);
post.setContent(content);
post.setCreateTime(new Date());
discussPostService.addDiscussPost(post);
//触发发帖实践
Event event =new Event()
.setTopic(TOPIC_PUBLISH)
.setUserId(user.getId())
.setEntityType(ENTITY_TYPE_POST)
.setEntityId(post.getId());
eventProducer.fireEvent(event);
String redisKey= RedisKeyUtil.getPostScoreKey();
redisTemplate.opsForSet().add(redisKey,post.getId());
//报错的情况,将来统一处理
return CommunityUtil.getJSONString(0,"发布成功!");
}
// 删除
@RequestMapping(path = "/delete", method = RequestMethod.POST)
@ResponseBody
public String setDelete(int id) {
discussPostService.updateStatus(id, 2);
// 触发删帖事件
Event event = new Event()
.setTopic(TOPIC_DELETE)
.setUserId(hostHolder.getUser().getId())
.setEntityType(ENTITY_TYPE_POST)
.setEntityId(id);
eventProducer.fireEvent(event);
return CommunityUtil.getJSONString(0);
}
EventConsumer
// 消费发帖事件
@KafkaListener(topics = {TOPIC_PUBLISH})
public void handlePublishMessage(ConsumerRecord record) {
if (record == null || record.value() == null) {
logger.error("消息的内容为空!");
return;
}
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
if (event == null) {
logger.error("消息格式错误!");
return;
}
DiscussPost post = discussPostService.findDiscussPostById(event.getEntityId());
elasticsearchService.saveDiscussPost(post);
}
// 消费删帖事件
@KafkaListener(topics = {TOPIC_DELETE})
public void handleDeleteMessage(ConsumerRecord record) {
if (record == null || record.value() == null) {
logger.error("消息的内容为空!");
return;
}
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
if (event == null) {
logger.error("消息格式错误!");
return;
}
elasticsearchService.deleteDiscussPost(event.getEntityId());
}
3.开发社区搜索功能
ElasticsearchService
public List<DiscussPost> searchDiscussPost(String keyword, int current, int limit) throws IOException {
SearchRequest searchRequest = new SearchRequest("discusspost");//discusspost是索引名,就是表名
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
//高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.field("content");
highlightBuilder.requireFieldMatch(false);
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.query(QueryBuilders.multiMatchQuery(keyword, "title", "content"))
.sort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
.sort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
.sort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
.from(current)// 指定从哪条开始查询
.size(limit)// 需要查出的总记录条数
.highlighter(highlightBuilder);//高亮
searchRequest.source(searchSourceBuilder);
//这有个异常
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
List<DiscussPost> list = new LinkedList<>();
for (SearchHit hit : searchResponse.getHits().getHits()) {
DiscussPost discussPost = JSONObject.parseObject(hit.getSourceAsString(), DiscussPost.class);
// 处理高亮显示的结果
HighlightField titleField = hit.getHighlightFields().get("title");
if (titleField != null) {
discussPost.setTitle(titleField.getFragments()[0].toString());
}
HighlightField contentField = hit.getHighlightFields().get("content");
if (contentField != null) {
discussPost.setContent(contentField.getFragments()[0].toString());
}
// System.out.println(discussPost);
list.add(discussPost);
}
return list;
}
最后
2023-7-31 20:34:10
这篇博客能写好的原因是:站在巨人的肩膀上
这篇博客要写好的目的是:做别人的肩膀
开源:为爱发电
学习:为我而行