日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

编程问答

项目1在线交流平台-6.Elasticsearch分布式搜索引擎-3.ES结合Kafka应用-开发社区搜索功能

發布時間:2023/12/29 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 项目1在线交流平台-6.Elasticsearch分布式搜索引擎-3.ES结合Kafka应用-开发社区搜索功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 功能需求
    • 一、Service層處理操作ES服務器的數據
    • 二、Controller層處理帖子添加和評論事件請求
      • 1.添加帖子時-觸發事件-發布消息
      • 2. 添加評論時-觸發發帖事件-發布消息
    • 三、kafka消費者訂閱消息并提交到ES服務器
    • 四、處理搜索結果
      • 1. Controller處理搜索請求
      • 2. 處理模板頁面
        • 主頁頭部的搜索欄鏈接
        • 搜索網頁設置
      • 測試結果:

參考牛客網高級項目教程
狂神說Elasticsearch教程筆記
尚硅谷Elasticsearch教程筆記

功能需求

  • 1.在業務層處理好搜索帖子的服務
    • 包括保存帖子到ES服務器
    • 從服務器中刪除帖子
    • 從服務器中查詢帖子
  • 2.發布事件
    • 在controller層,結合kafka,發布帖子、增加評論時,數據放入消息隊列
    • 異步消費消息,將數據同步到ES服務器
  • 3.處理模板頁面的顯示,搜索帖子時,根據關鍵字顯示出滿足條件的帖子列表

一、Service層處理操作ES服務器的數據

  • 向服務器添加一條帖子
  • 刪除一條帖子
  • 根據關鍵字查詢帖子列表
  • 注意,keyword本身為字符串,不能再加”“號
@Service public class ElasticSearchService {@AutowiredDiscussPostMapper discussPostMapper;@AutowiredDiscussPostRepository repository;@AutowiredElasticsearchTemplate elasticTemplate;/*** 向服務器添加一條帖子*/public void savePost(DiscussPost discussPost) {repository.save(discussPost);}/*** 刪除一條帖子*/public void deletePost(DiscussPost discussPost) {repository.delete(discussPost);}/*** 根據關鍵字查詢帖子列表*/public Page<DiscussPost> searchPosts(String keyword, int current, int limit) {// 1.構建查詢條件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();// 2.處理查詢的結果-拼接高亮顯示的部分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());}});} }

二、Controller層處理帖子添加和評論事件請求

1.添加帖子時-觸發事件-發布消息

// 發布帖子后,觸發發帖事件-向kafka服務器發布消息 Event event = new Event().setTopic(TOPIC_PUBLISH).setFromUserId(user.getId()).setEntityType(ENTITY_TYPE_POST).setEntityId(discussPost.getId()); eventProducer.sendEvent(event);

2. 添加評論時-觸發發帖事件-發布消息

  • 因為對帖子發布評論后,帖子的字段需要更新,為保證數據一致性,需要重新發布事件
if (comment.getEntityType() == ENTITY_TYPE_POST) {// 觸發發帖事件event = new Event().setTopic(TOPIC_PUBLISH).setFromUserId(comment.getUserId()).setEntityType(ENTITY_TYPE_POST).setEntityId(discussPostId);eventProducer.sendEvent(event); }

三、kafka消費者訂閱消息并提交到ES服務器

/*** 消費發布帖子的消息-將帖子數據提交到ES服務器* @param record*/ @KafkaListener(topics = TOPIC_PUBLISH) public void handlePublishMessage(ConsumerRecord record) {// 1.邊界條件:先檢查有無取到消息if (record == null || record.value() == null) {logger.error("消息的內容為空!");return;}// 2.將拿到的消息恢復成Object類型,方便操作Event event = JSONObject.parseObject(record.value().toString(), Event.class);if(event == null) {logger.error("消息的格式錯了!");return;}// 3. 將拿到的消息添加到ES服務器中DiscussPost discussPost = discussPostService.selectPostById(event.getEntityId());elasticSearchService.savePost(discussPost); }

四、處理搜索結果

1. Controller處理搜索請求

  • 搜索帖子-分頁搜索-頁面默認設置當前頁為1,limit為10

  • 注意-需要的分頁信息是-當前頁碼和當前頁數量,

    • 與mysql查詢的分頁條件不同(起始行-當前頁顯示多少行)

/*** 根據關鍵字搜索查詢帖子請求* @param keyword* @param model* @param page* @return*/ @RequestMapping(value = "/search", method = RequestMethod.GET) public String search(String keyword, Model model, Page page) {// 搜索帖子-分頁搜索-頁面默認設置當前頁為1,limit為10// 注意-需要的分頁信息是-當前頁碼和當前頁數量,與mysql查詢的分頁條件不同(起始行-當前頁顯示多少行)org.springframework.data.domain.Page<DiscussPost> searchResult= elasticSearchService.searchPosts(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"; }

2. 處理模板頁面

主頁頭部的搜索欄鏈接

<!-- 搜索 --> <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>

搜索網頁設置

<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" style="width:50px;height:50px;" alt="用戶頭像"><div class="media-body"><h6 class="mt-0 mb-3"><a th:href="@{|/discuss/detail/${map.post.id}|}" th:utext="${map.post.title}">備戰<em>春招</em>,面試刷題跟他復習,一個月全搞定!</a></h6><div class="mb-3" th:utext="${map.post.content}">帖子內容</div><div class="text-muted font-size-12"><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></div></div> </li>

測試結果:

總結

以上是生活随笔為你收集整理的项目1在线交流平台-6.Elasticsearch分布式搜索引擎-3.ES结合Kafka应用-开发社区搜索功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。