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

这篇具有很好参考价值的文章主要介绍了项目1在线交流平台-6.Elasticsearch分布式搜索引擎-3.ES结合Kafka应用-开发社区搜索功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


参考牛客网高级项目教程
狂神说Elasticsearch教程笔记
尚硅谷Elasticsearch教程笔记

功能需求

  • 1.在业务层处理好搜索帖子的服务
    • 包括保存帖子到ES服务器
    • 从服务器中删除帖子
    • 从服务器中查询帖子
  • 2.发布事件
    • 在controller层,结合kafka,发布帖子、增加评论时,数据放入消息队列
    • 异步消费消息,将数据同步到ES服务器
  • 3.处理模板页面的显示,搜索帖子时,根据关键字显示出满足条件的帖子列表
项目1在线交流平台-6.Elasticsearch分布式搜索引擎-3.ES结合Kafka应用-开发社区搜索功能

一、Service层处理操作ES服务器的数据

  • 向服务器添加一条帖子
  • 删除一条帖子
  • 根据关键字查询帖子列表
  • 注意,keyword本身为字符串,不能再加”“号
@Service
public class ElasticSearchService {
    @Autowired
    DiscussPostMapper discussPostMapper;
    @Autowired
    DiscussPostRepository repository;
    @Autowired
    ElasticsearchTemplate 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() {
            @Override
            public <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查询的分页条件不同(起始行-当前页显示多少行)

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

/**
 * 根据关键字搜索查询帖子请求
 * @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应用-开发社区搜索功能

项目1在线交流平台-6.Elasticsearch分布式搜索引擎-3.ES结合Kafka应用-开发社区搜索功能文章来源地址https://www.toymoban.com/news/detail-432266.html

到了这里,关于项目1在线交流平台-6.Elasticsearch分布式搜索引擎-3.ES结合Kafka应用-开发社区搜索功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 史上最全从零搭建ELKB(Elasticsearch、Logstash、Kibana、Beat)分布式日志管理可视化平台之一

    ELKB(Elasticsearch、Logstash、Kibana、Beat的组合)是一套开源的分布式日志管理方案。凭借其闭环的日志处理流程、高效的检索性能、线性的扩展能力、较低的运维成本等特点,ELKB在最近几年迅速崛起,成为实时日志处理开源领域的首要选择。(https://cloud.tencent.com/developer/article/1143

    2024年01月19日
    浏览(45)
  • 搭建一个问答交流平台

    弄了个视频号下载后,同一个问题每天都会被问,回答的有点烦了。想了想根本原因还是缺少一个交流平台,微信群的话,刚进群的看不到之前的聊天记录。想整个知识星球,发现只能弄个收费的,免费的需要激活码才能创建。 而有些人不会使用github,所以这篇文章写一下如

    2024年04月22日
    浏览(21)
  • 冲量在线中标山大地纬数据隐私安全平台项目,联合共建区块链+隐私计算的数据开放新范式

    近日,冲量在线中标山大地纬数据隐私安全平台项目,共同打造业界领先的基于“区块链+隐私计算”的数据开放平台,开创了隐私计算平台互联互通新模式。实现了多个医疗机构、保险公司、金融机构、社保部门等多方的数据进行联合运算,在医保社保报销结算、普惠金融

    2024年02月12日
    浏览(29)
  • 【分布式任务调度平台 XXL-JOB 急速入门】从零开始将 XXL-JOB 接入到自己的项目

                                    💧 分布式任务调度平台 X X L − J O B 急速入门:从零开始将 X X L − J O B 接入到自己的项目 color{#FF1493}{分布式任务调度平台 XXL-JOB 急速入门:从零开始将 XXL-JOB 接入到自己的项目} 分布式任务调度平台 XX L − J OB 急速入门:从零

    2024年02月14日
    浏览(30)
  • 电影交流|基于SprinBoot+vue的电影交流平台小程序系统(源码+数据库+文档)

    电影交流平台 目录 目录 基于SprinBoot+vue的电影交流平台小程序系统  一、前言  二、系统设计 三、系统功能设计  1用户信息管理 2 电影信息管理 3公告信息管理 4论坛信息管理 四、数据库设计  五、核心代码  六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博

    2024年04月27日
    浏览(23)
  • Springboot+Vue项目-基于Java+MySQL的在线视频教育平台系统(附源码+演示视频+LW)

    大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 🌎微信小程序毕业设计 开发语言:Java 框架:Springboot+Vue JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat12 开发软件

    2024年04月13日
    浏览(33)
  • nodejs+vue网上学习交流平台

    网上学习交流网站的建设,主要分为前台和后台的模式开发实现的,  数据库选用了中小型数据库mysql进行数据的管理。网站核心功能是学习资料的下载和学习问题的交流,用户之间可以产生互动。在线学习已经成为了当前一个比较主流一种学习交流的方式,很多人通过在网

    2023年04月19日
    浏览(28)
  • 基于web的考研信息交流平台/考研信息分享平台的设计与实现

      摘 要 随着信息化时代的到来,管理系统都趋向于智能化、系统化, 考研信息交流平台 也不例外,但目前国内的 有些平台 仍 然 都使用人工管理, 浏览网站人数越来越多 ,同时信息量也越来越庞大,人工管理显然已无法应对时代的变化,而 考研信息交流平台 能很好地解

    2024年02月16日
    浏览(56)
  • 微信小程序|英语学习交流平台小程序

    作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、Python项目、前端项目、人工智能与大数据、简历模板、学习资料、面试题库、技术互助 收藏点赞不

    2024年04月25日
    浏览(27)
  • java+springboot+mysql大学图书共享交流平台

    项目介绍: 使用java+ssm+mysql开发的大学图书共享交流平台,系统包含超级管理员,系统管理员、用户角色,功能如下: 用户:主要是前台功能使用,包括注册、登录;查看图书交流(发布、查看、借阅、评论、收藏图书),系统留言,关于我们, 用户还具备个人中心功能:

    2024年02月15日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包