仿牛客网项目---Elasticsearch分布式搜索引擎

news2024/11/16 19:34:14

1.什么是ElasticSearch分布式搜索引擎?

Elasticsearch是一个开源的分布式搜索引擎,提供实时的、高可用性的搜索和分析解决方案。它支持快速索引和搜索大规模数据,具有分布式架构、RESTful API、基于JSON的查询语言等功能,适用于各种应用场景,如全文搜索。

比如说现在,我拥有一个电子商务网站,然后我需要一个搜索引擎来让用户能够快速地搜索和找到他们感兴趣的商品。这时候,我就可以使用Elasticsearch作为你的分布式搜索引擎。

假设现在我的电子商务网站有几百万个商品,并且我希望用户可以根据商品的名称、描述、价格、品牌等信息进行搜索。

首先,我会使用Elasticsearch的API将商品数据索引到Elasticsearch集群中。每个商品将被表示为一个文档,包含属性如商品名称、描述、价格等。

当用户在我的网站上进行搜索时,我就可以使用Elasticsearch的搜索API发送一个搜索请求。比如,用户搜索关键词"手机"。

Elasticsearch将会在索引中查找包含关键词"手机"的所有文档,并返回匹配的结果。

2.项目中的搜索功能实现

在Dao层中新建Elasticsearch文件,添加Elasticsearch接口,用于连接数据库(只需要继承接口即可)。

@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {
 
}

上面的代码其实是用Elasticsearch创建一个帖子的仓库接口,以便在应用程序中访问和操作Elasticsearch中的帖子数据。这个相对而言比较简单。

service层写一个ElasticsearchService文件。

@Service
public class ElasticsearchService {
 
    @Autowired
    private DiscussPostRepository discussRepository;
 
    @Autowired
    private ElasticsearchTemplate elasticTemplate;
 
    public void saveDiscussPost(DiscussPost post) {
        discussRepository.save(post);
    }
 
    public void deleteDiscussPost(int id) {
        discussRepository.deleteById(id);
    }
 
    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() {
            @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());
            }
        });
    }
 
}

上述代码展示了一个名为 ElasticsearchService 的服务类,它提供了以下功能:

  1. saveDiscussPost 方法用于将帖子数据保存到 Elasticsearch 中。它接收一个 DiscussPost 对象作为参数,并调用 discussRepository 的 save 方法将数据保存到 Elasticsearch 中。

  2. deleteDiscussPost 方法用于从 Elasticsearch 中删除指定 ID 的数据。它接收一个整数类型的 ID 参数,并调用 discussRepository 的 deleteById 方法来删除数据。

  3. searchDiscussPost 方法用于在 Elasticsearch 中搜索帖子数据。它接收关键字、当前页码和每页显示数量作为参数,并执行一个复杂的搜索查询。将查询结果封装成一个 Page<DiscussPost> 对象返回。

上面说了很多,其实你只要知道这段代码作用就是这样的,ElasticsearchService 提供了对 Elasticsearch 中讨论帖子数据的保存、删除和搜索功能。它充分利用了 Spring Data Elasticsearch 和 ElasticsearchTemplate 提供的功能和方法,简化了与 Elasticsearch 的交互和操作。该服务类可以被其他组件或业务逻辑调用,以实现对 Elasticsearch 数据的管理和检索。

在Controller层写一个SearchController文件。

@Controller
public class SearchController implements CommunityConstant {
 
    @Autowired
    private ElasticsearchService elasticsearchService;
 
    @Autowired
    private UserService userService;
 
    @Autowired
    private LikeService likeService;
 
    // 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";
    }
 
}

这段代码的作用是展示了一个名为 SearchController 的控制器类,用于处理搜索功能的请求。

  1. 接收用户输入的关键字 keyword、分页信息 page 和模型对象 model

  2. 调用 elasticsearchService 的 searchDiscussPost 方法,传递关键字、当前页码和每页显示数量,以执行搜索操作。

  3. 将搜索结果 searchResult 中的每个帖子,以及帖子的作者和点赞数量等信息,存储在 discussPosts 列表中的 Map 对象中。

  4. 将 discussPosts、关键字 keyword 和分页信息 page 添加到模型对象 model 中,以便在视图中进行展示。

看了这么多,反正你要知道的就是SearchController 控制器类负责接收用户的搜索请求,调用 ElasticsearchService 执行搜索操作,获取搜索结果,并将结果和相关信息传递给视图进行展示。通过这个控制器类,用户可以在前端页面输入关键字进行搜索,然后获取搜索结果并在页面上显示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1508562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Asp .Net Web Forms 系列:配置图片防盗链的几种方法

通过 URL Rewrite Module 组件 URL Rewrite Module 是一个用于在 ASP.NET Web Forms 或其他基于 IIS 的 Web 应用程序中重写 URL 的强大工具。这个模块允许你将复杂的、不易于记忆或不利于搜索引擎优化的 URL 转换为更简洁、更友好的格式。通过 URL 重写&#xff0c;你可以提高…

Upload 上传(图片/文件),回显(图片),下载(文件)

1.前端技术&#xff1a;V3 Ant Design Vue 2.后端技术&#xff1a;Java 图片上传/回显&#xff1a; 文件上传回显&#xff1a; 表结构&#xff1a;单文件/图片上传为A表对文件C表 &#xff08;A表field字段 对应 C表id字段&#xff09; 如图&#xff1a;A表中的 vehicle_d…

leetcode代码记录和对比(两数相加

目录 1. 题目&#xff1a;2. 我的代码&#xff1a;3. 别人的代码&#xff1a;小结&#xff1a; 1. 题目&#xff1a; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个…

世界排名第二的大语言模型,你听说过吗?

前言&#xff1a; 在介绍这个大语言模型之前&#xff0c;我们需要先来回顾一个事情&#xff0c;大家应该都知道&#xff0c;在去年 11 月&#xff0c;OpenAI 经历了 CEO Altman 被解雇&#xff08;后又重返&#xff09;的风波。而微软作为OpenAI的最大股东&#xff0c;直至Alt…

【DAY10 软考中级备考笔记】数据结构 图

数据结构 图 3月11日 – 天气&#xff1a;晴 晚上无线网络突然不能用了&#xff0c;花费好久弄这个&#xff0c;耽误了一些时间 1. 图的定义 这里需要注意完全图的定义&#xff0c;以及完全图的边数 这里需要注意连通图和连通分量的概念。 2. 图的存储结构 图有两种存储结构&a…

PortSwigger 基于dom的漏洞-利用 DOM 破坏来启用 XSS

进入实验随意进入一篇博客 我们可以尝试随意提交一些恶意代码看看会发生什么 很显然我们提交成功了但是我们的恶意代码貌似被过滤了 查看源码发现这里有一个过滤框架 我们打开源码分析 function loadComments(postCommentPath) {let xhr new XMLHttpRequest();xhr.onreadys…

植物病害识别:YOLO水稻病害识别/分类数据集(2000多张,2个类别,yolo标注)

YOLO水稻病害识别/分类数据集&#xff0c;包含疾病和正常2类&#xff0c;共2000多张图像&#xff0c;yolo标注完整&#xff0c;可直接训练。 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 需要此数据集或其他任何数据集请私信

基于单片机的视觉导航小车设计

目 录 摘 要 I Abstract II 引 言 1 1 总体方案设计 3 1.1 方案论证 3 1.2 项目总体设计 3 2 项目硬件设计 4 2.1 主控模块设计 4 2.1.1单片机选型 4 2.1.2 STM32F103RCT6芯片 4 2.2单片机最小系统电路 5 2.3电机驱动模块设计 7 2.4红外模块设计 8 2.5红外遥控模块设计 9 2.6超…

Logseq电脑端+安卓端同步gitee或github

文章目录 0.初衷1.电脑端1.1 新建仓库1.2 克隆项目&#xff0c;生成秘钥1.3 添加图谱&#xff0c;选择文件目录&#xff0c;我是原本就有笔记&#xff0c;所以会如下所示。1.4 下载脚本文件1.5赋权限 &#xff08;windows可跳过&#xff09;1.6 修改脚本命令1.7 logseq设置同步…

Docker命令大全与实例详解

本文旨在汇总和深入解析日常工作与学习中频繁接触到的Docker核心命令&#xff0c;通过实例演示来巩固记忆&#xff0c;以便读者在实际操作中迅速查阅和高效运用。Docker作为一种轻量级容器技术&#xff0c;已经成为现代应用部署与管理的重要工具。本文将涵盖从基本的Docker环境…

公网ip和局域网ip

什么是公网IP&#xff1f; 公网&#xff0c;俗称外网&#xff0c;又被叫做互联网&#xff0c;是连接不同地区局域网或者城域网计算机的通信的远程网络。通常可以跨接很大的物理范围&#xff0c;连接多个地区、城市和国家提供远距离通信&#xff0c;形成全球性的互联网络。因此…

MySQL临时表创建出错(OS errno 13 - Permission denied)

一个客户向我抱怨&#xff1a;在MySQL查询小表没有问题&#xff0c;查询大表出错&#xff0c;下面是他发给我的出错的部分截屏&#xff08;客户的表名被我隐藏了&#xff09;。 这里的给出的信息已经比较明显了&#xff0c;是向/tmp目录中创建临时表失败&#xff08;临时表的路…

555经典电路

1、555介绍&#xff1a; 555 定时器是一种模拟和数字功能相结合的中规模集成器件。一般用双极性工艺制作的称为 555&#xff0c;用 CMOS 工艺制作的称为 7555&#xff0c;除单定时器外&#xff0c;还有对应的双定时器 556/7556。555 定时器的电源电压范围宽&#xff0c;可在 4…

YoLo进化史《A COMPREHENSIVE REVIEW OF YOLO: FROM YOLOV1 TOYOLOV8 AND BEYOND》

Abstract YOLO已成为机器人、无人驾驶汽车和视频监控应用的核心实时目标检测系统。我们对YOLO的发展进行了全面的分析&#xff0c;研究了从最初的YOLO到YOLOv8的每次迭代中的创新和贡献。我们首先描述标准指标和后处理;然后&#xff0c;我们讨论了网络架构的主要变化和每个模型…

工具篇--分布式定时任务springBoot--elasticjob简单使用(1)

文章目录 前言一、elasticjob 介绍&#xff1a;二、elasticjob 使用&#xff1a;2.1 部署zookeeper&#xff1a;2.2 引入库2.2 定义任务&#xff1a;2.3 任务执行&#xff1a;2.4 任务执行控制台输出&#xff1a; 三、elasticjob 启动错误&#xff1a;3.1 KeeperErrorCode Ope…

数据结构->双向链表带你体验开火车(哨兵)与拼接火车(应用)厢的乐趣

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;橘橙黄又青-CSDN博客 目的&#xff1a;学习双向带头链表的增&#xff0c;删&#xff0c;查&#xff0c;销毁…

Vue+SpringBoot打造个人健康管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 健康档案模块2.2 体检档案模块2.3 健康咨询模块 三、系统展示四、核心代码4.1 查询健康档案4.2 新增健康档案4.3 查询体检档案4.4 新增体检档案4.5 新增健康咨询 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpri…

PyTorch 源码解读之 torch.cuda.amp: 自动混合精度详解

PyTorch 源码解读之 torch.cuda.amp: 自动混合精度详解 Nvidia 在 Volta 架构中引入 Tensor Core 单元&#xff0c;来支持 FP32 和 FP16 混合精度计算。也在 2018 年提出一个 PyTorch 拓展 apex&#xff0c;来支持模型参数自动混合精度训练。自动混合精度&#xff08;Automati…

2024.03.11作业

1. 提示并输入一个字符串&#xff0c;统计该字符串中大写小写字母个数&#xff0c;数字个数&#xff0c;空格个数以及其他字符个数&#xff0c;要求使用c风格字符串完成 #include <iostream> #include <string>using namespace std;int main() {cout << &qu…

蓝桥杯2023年第十四届Java省赛真题-矩形总面积

题目描述 平面上有个两个矩形 R1 和 R2&#xff0c;它们各边都与坐标轴平行。设 (x1, y1) 和(x2, y2) 依次是 R1 的左下角和右上角坐标&#xff0c;(x3, y3) 和 (x4, y4) 依次是 R2 的左下角和右上角坐标&#xff0c;请你计算 R1 和 R2 的总面积是多少&#xff1f; 注意&…