欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网项目——项目开发(八):开发社区搜索功能

发布时间:2023/12/29 编程问答 32 豆豆
生活随笔 收集整理的这篇文章主要介绍了 牛客网项目——项目开发(八):开发社区搜索功能 小编觉得挺不错的,现在分享给大家,帮大家做个参考.


文章目录

  • 1. ElasticsearchService
    • 1.1 注入bean
    • 1.2 保存(修改)和删除
    • 1.3 搜索 searchDiscussPost
  • 2. DiscussPostController.addDiscussPost
  • 3. CommentController.addComment
  • 4. EventConsumer.handlePublishMessage
  • 5. SearchController
    • 5.1 注入属性
    • 5.2 搜索帖子
  • 6. index.html
  • 7. search.html

1. ElasticsearchService

1.1 注入bean

@Autowired private DiscussPostRepository discussRepository;@Autowired private ElasticsearchTemplate elasticTemplate;

1.2 保存(修改)和删除

public void saveDiscussPost(DiscussPost post) {discussRepository.save(post); }public void deleteDiscussPost(int id) {discussRepository.deleteById(id); }

1.3 搜索 searchDiscussPost

  • 返回参数:Page类型数据,封装多条数据
  • 传入参数:关键字keyword,当前页数current,每页显示数据limit
  • 搜索逻辑,参考前置技术(九)
  • 查询关键字
  • 排序
  • 分页
  • 高亮显示
  • 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();return elasticTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() {@Overridepublic <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {SearchHits hits = response.getHits();if (hits.getTotalHits() <= 0) {return null;}List<DiscussPost> list = new ArrayList<>();for (SearchHit hit : hits) {DiscussPost post = new DiscussPost();String id = hit.getSourceAsMap().get("id").toString();post.setId(Integer.valueOf(id));String userId = hit.getSourceAsMap().get("userId").toString();post.setUserId(Integer.valueOf(userId));String title = hit.getSourceAsMap().get("title").toString();post.setTitle(title);String content = hit.getSourceAsMap().get("content").toString();post.setContent(content);String status = hit.getSourceAsMap().get("status").toString();post.setStatus(Integer.valueOf(status));String createTime = hit.getSourceAsMap().get("createTime").toString();post.setCreateTime(new Date(Long.valueOf(createTime)));String commentCount = hit.getSourceAsMap().get("commentCount").toString();post.setCommentCount(Integer.valueOf(commentCount));// 处理高亮显示的结果HighlightField titleField = hit.getHighlightFields().get("title");if (titleField != null) {post.setTitle(titleField.getFragments()[0].toString());}HighlightField contentField = hit.getHighlightFields().get("content");if (contentField != null) {post.setContent(contentField.getFragments()[0].toString());}list.add(post);}return new AggregatedPageImpl(list, pageable,hits.getTotalHits(), response.getAggregations(), response.getScrollId(), hits.getMaxScore());}}); }

    2. DiscussPostController.addDiscussPost

    发帖后把帖子存入es

    @Autowired private EventProducer eventProducer;// 触发发帖事件 Event event = new Event().setTopic(TOPIC_PUBLISH).setUserId(user.getId()).setEntityType(ENTITY_TYPE_POST).setEntityId(post.getId()); eventProducer.fireEvent(event);

    CommunityConstant 中增加常量

    /*** 主题: 发帖*/ String TOPIC_PUBLISH = "publish";

    3. CommentController.addComment

    触发评论帖子事后后触发发帖事件

    if (comment.getEntityType() == ENTITY_TYPE_POST) {// 触发发帖事件event = new Event().setTopic(TOPIC_PUBLISH).setUserId(comment.getUserId()).setEntityType(ENTITY_TYPE_POST).setEntityId(discussPostId);eventProducer.fireEvent(event); }

    4. EventConsumer.handlePublishMessage

    消费发帖事件

    // 消费发帖事件 @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); }

    5. SearchController

    5.1 注入属性

    @Autowired private ElasticsearchService elasticsearchService;@Autowired private UserService userService;@Autowired private LikeService likeService;

    5.2 搜索帖子

  • 调用service查询
  • 把数据存入一个map
  • 把数据传给模板
  • 传递分页信息
  • // search?keyword=xxx @RequestMapping(path = "/search", method = RequestMethod.GET) public String search(String keyword, Page page, Model model) {// 搜索帖子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"; }

    6. index.html

    <!-- 搜索 --> <form class="form-inline my-2 my-lg-0" method="get" th:action="@{/search}"><input class="form-control mr-sm-2" type="search" aria-label="Search" name="keyword" th:value="${keyword}"/><button class="btn btn-outline-light my-2 my-sm-0" type="submit">搜索</button> </form>

    7. search.html

  • 模板
  • 路径
  • 头部复用
  • js路径
  • 遍历
  • <li class="media pb-3 pt-3 mb-3 border-bottom" th:each="map:${discussPosts}">
  • 头像
  • <img th:src="${map.user.headerUrl}" class="mr-4 rounded-circle" alt="用户头像" style="width:50px;height:50px;">
  • 标题
  • <h6 class="mt-0 mb-3"><a th:href="@{|/discuss/detail/${map.post.id}|}" th:utext="${map.post.title}">备战<em>春招</em>,面试刷题跟他复习,一个月全搞定!</a> </h6>
  • 帖子作者
  • <u class="mr-3" th:utext="${map.user.username}">寒江雪</u>
  • 发布时间,赞,回复信息
  • 发布于 <b th:text="${#dates.format(map.post.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b> <ul class="d-inline float-right"><li class="d-inline ml-2"><i th:text="${map.likeCount}">11</i></li><li class="d-inline ml-2">|</li><li class="d-inline ml-2">回复 <i th:text="${map.post.commentCount}">7</i></li> </ul>
  • 分页复用
  • <!-- 分页 --> <nav class="mt-5" th:replace="index::pagination"><ul class="pagination justify-content-center"><li class="page-item"><a class="page-link" href="#">首页</a></li><li class="page-item disabled"><a class="page-link" href="#">上一页</a></li><li class="page-item active"><a class="page-link" href="#">1</a></li><li class="page-item"><a class="page-link" href="#">2</a></li><li class="page-item"><a class="page-link" href="#">3</a></li><li class="page-item"><a class="page-link" href="#">4</a></li><li class="page-item"><a class="page-link" href="#">5</a></li><li class="page-item"><a class="page-link" href="#">下一页</a></li><li class="page-item"><a class="page-link" href="#">末页</a></li></ul> </nav>

    总结

    以上是生活随笔为你收集整理的牛客网项目——项目开发(八):开发社区搜索功能的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。