校园课程助手【4】-使用Elasticsearch实现课程检索

本节将介绍本项目的查询模块,使用Elasticsearch又不是查询接口,具体流程如图所示(如果不了解Elasticsearch可以使用sql语句进行查询):
在这里插入图片描述
这里是两种方法的异同点:

  • Mysql:擅长事务类型操作,可以确保数据的安全和一致性
  • Elasticsearch:擅长海量数据的搜索、分析、计算
  • 对安全性要求较高的写操作,使用mysql实现
  • 对查询性能要求较高的搜索需求,使用elasticsearch实现
  • 两者再基于某种方式,实现数据的同步,保证一致性

具体流程:

1.导入依赖

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>

2.在application.yum引入配置

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>

3.在项目中建立elasticsearch.document和elasticsearch.repository包,用于存放elasticsearch文档类和接口操作

package com.java.elasticsearch.document;import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;import java.math.BigDecimal;@Document(indexName = "course")
public class CourseInfo {@Idprivate String courseId;@Field(type = FieldType.Text, analyzer = "standard") // 使用标准分析器private String courseName;@Field(type = FieldType.Text, analyzer = "standard") // 使用标准分析器private String courseTeacher;@Field(type = FieldType.Text)private String courseDetail;@Field(type = FieldType.Integer)private Integer courseAttribute;@Field(type = FieldType.Double)private BigDecimal coursePrice;@Field(type = FieldType.Integer)private Integer courseStock;// 构造函数、getter 和 setter 方法// Getters and setters for each fieldpublic String getCourseId() {return courseId;}public void setCourseId(String courseId) {this.courseId = courseId;}public String getCourseName() {return courseName;}public void setCourseName(String courseName) {this.courseName = courseName;}public String getCourseTeacher() {return courseTeacher;}public void setCourseTeacher(String courseTeacher) {this.courseTeacher = courseTeacher;}public String getCourseDetail() {return courseDetail;}public void setCourseDetail(String courseDetail) {this.courseDetail = courseDetail;}public Integer getCourseAttribute() {return courseAttribute;}public void setCourseAttribute(Integer courseAttribute) {this.courseAttribute = courseAttribute;}public BigDecimal getCoursePrice() {return coursePrice;}public void setCoursePrice(BigDecimal coursePrice) {this.coursePrice = coursePrice;}public Integer getCourseStock() {return courseStock;}public void setCourseStock(Integer courseStock) {this.courseStock = courseStock;}
}

4、在repository包下新建操作Elasticsearch的接口继承ElasticsearchRepository

package com.java.elasticsearch.repository;import com.java.elasticsearch.document.CourseInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;public interface CourseRepository extends ElasticsearchRepository<CourseInfo, String> {// 按课程名查询Page<CourseInfo> findByCourseName(String courseName, int courseAttribute, Pageable pageable);// 按授课老师名查询Page<CourseInfo> findByCourseTeacher(String courseTeacher, int courseAttribute,Pageable pageable);// 查询课程名为courseName且授课老师为courseTeacher的记录@Query("{\"bool\": {\"must\": [{\"match\": {\"courseName\": \"?0\"}}, {\"match\": {\"courseTeacher\": \"?1\"}}]}}")Page<CourseInfo> findByCourseNameAndCourseTeacher(String courseName, String courseTeacher, Pageable pageable);
}

5.在service包下新建Elasticsearch课程搜索Service类EsCourseService

package com.java.service;import com.java.elasticsearch.document.EsCourse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;import java.util.List;public interface EsCourseService {/*** 从数据库中导入课程到ES* @return*/int importAll();/*** 根据id删除课程* @param id*/void delete(Long id);/*** 根据id创建商品* @param id* @return*/EsProduct create(Long id);/*** 批量删除* @param ids*/void deletes(List<Long> ids);/*** 根据关键字搜索* @param keyword* @param pageNum* @param pageSize* @return*/Page<EsProduct> searchPage(String keyword, Integer pageNum,Integer pageSize);
}

实现上述方法

package com.java.service.impl;import com.java.dao.EsProductDao;
import com.java.elasticsearch.document.EsProduct;
import com.java.elasticsearch.repository.EsProductRepository;
import com.java.service.EsProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;@Service
@Transactional
public class EsProductServiceImpl implements EsProductService {private static final Logger logger = LoggerFactory.getLogger(EsProductServiceImpl.class);@Autowiredprivate EsProductDao esProductDao;@Autowiredprivate EsProductRepository esProductRepository;@Overridepublic int importAll() {List<EsProduct> esProductList = esProductDao.getProductEs(null);Iterable<EsProduct> iterable = esProductRepository.saveAll(esProductList);Iterator<EsProduct> iterator = iterable.iterator();logger.info("导入ES数据{}:",iterator);int count = 0;while (iterator.hasNext()) {count++;iterator.next();}return count;}@Overridepublic void delete(Long id) {logger.info("删除ES中的商品{}:",id);esProductRepository.deleteById(id);}@Overridepublic EsProduct create(Long id) {List<EsProduct> esProducts = esProductDao.getProductEs(id);if (CollectionUtils.isEmpty(esProducts)) {return null;}EsProduct esProduct = esProducts.get(0);logger.info("导入ES单条商品{}:",esProduct);return esProductRepository.save(esProduct);}@Overridepublic void deletes(List<Long> ids) {if (!CollectionUtils.isEmpty(ids)) {List<EsProduct> esProductList = new ArrayList<>();ids.forEach(id->{EsProduct esProduct = new EsProduct();esProduct.setId(id);esProductList.add(esProduct);});logger.info("批量删除ES中的商品{}:",esProductList);esProductRepository.deleteAll(esProductList);}}@Override// 搜索课程public Page<CourseInfo> searchCourses(String query, Integer courseAttribute, Pageable pageable) {if (query != null && !query.isEmpty()) {return courseRepository.findByCourseNameOrCourseTeacher(query, query, pageable);} else {// 如果没有搜索词,则返回所有符合条件的课程return courseRepository.findByCourseAttributeAndCourseStockGreaterThan(courseAttribute, pageable);}}
}

6.在dao包下新建操作数据库接口EsProductDao和映射xml文件EsProductDao.xml

package com.java.dao;
import java.util.List;public interface EsCourseDao {List<EsProduct> selectAllCourse();
}
<!-- src/main/resources/mapper/EsCourseDao.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.java.dao.EsProductDao"><resultMap id="CourseResultMap" type="EsCourse"><result property="course_id" column="course_id"/><result property="course_name" column="course_name"/><result property="course_teacher" column="course_teacher"/><result property="course_attribute" column="course_attribute"/><result property="course_stock" column="course_stock"/></resultMap><!-- 查询所有课程 --><select id="selectAllCourse" resultMap="CourseResultMap">SELECT course_id,course_name,course_teacher,course_attribute ,course_stockFROM course</select></mapper>

7.在controller包下新建控制器EsProductController


/*** ES搜索课程Controller**/
@Controller
@Api(tags = "EsProductController",description = "ES课程搜索")
public class EsProductController {@Autowiredprivate EsProductService esProductService;@ApiOperation("从数据库导入ES课程数据")@RequestMapping(value = "/esProduct/importAll",method = RequestMethod.POST)@ResponseBodypublic CommonResult<Integer> importAll(){int count = esProductService.importAll();return CommonResult.success(count);}@ApiOperation("根据id删除课程")@RequestMapping(value = "/esProduct/delete/{id}",method = RequestMethod.POST)@ResponseBodypublic CommonResult deleteById(@PathVariable Long id){esProductService.delete(id);return RespBean.success("删除成功");}@ApiOperation("批量删除课程")@RequestMapping(value = "/esProduct/deletes",method = RequestMethod.POST)@ResponseBodypublic CommonResult deleteById(List<Long> ids){esProductService.deletes(ids);return RespBean.success("删除成功");}@ApiOperation("根据id创建课程")@RequestMapping(value = "/esProduct/create",method = RequestMethod.POST)@ResponseBodypublic CommonResult create(Long id){EsProduct esProduct = esProductService.create(id);if (StringUtils.isEmpty(esProduct)) {return CommonResult.failed("创建失败");}return RespBean.success("创建成功");}@ApiOperation("搜索课程")@RequestMapping(value = "/esProduct/search",method = RequestMethod.GET)@ResponseBodypublic CommonResult<CommonPage<EsProduct>> search(@RequestParam(required = false) String keyword,@RequestParam(required = false, defaultValue = "0") Integer pageNum,@RequestParam(required = false, defaultValue = "5") Integer pageSize){Page<EsProduct> esProductPage = esProductService.searchPage(keyword,pageNum,pageSize);return RespBean.success(CommonPage.restPage(esProductPage));}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP苹果 V X iPhone微商i o s多分开V X语音转发密友朋友圈一键跟圈软件

苹果VX神器&#xff01;iPhone微商必备&#xff1a;ios多开、VX语音转发、密友朋友圈一键跟圈软件大揭秘&#xff01; 一、iOS多开新境界&#xff0c;工作生活两不误&#xff01; 你是不是也烦恼过&#xff0c;想要在工作号和生活号之间自由切换&#xff0c;却因为iPhone的限制…

【C++程序设计】——利用数组处理批量数据(一)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-削好皮的Pineapple! &#x1f468;‍&#x1f4bb; hello 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 削好皮的Pineapple! 原创 &#x1f468;‍&#x1f4…

【LeetCode每日一题】盛最多水的容器

思路 标签:双指针&#xff0c;贪心 分析&#xff1a; 首先选两条线为容器的两端&#xff0c;盛水的高度取决于高度小的那条线&#xff0c;此时在两条线中间选一条线&#xff0c;有两种情况&#xff0c;如果区间内某条线比两端高度小的那条线还要小&#xff0c;此时宽度和高度…

PLC控制器-耦合变压器的作用

华强盛电子导读&#xff1a;PLC耦合变压器 &#xff0c;前面199中间2643后面0038完。 耦合变压器在电子电路中扮演着重要的角色&#xff0c;尤其是在模拟电路的构建中。它的主要作用可以从以下几个方面进行详细阐述&#xff1a; 1. **信号耦合**&#xff1a; - 耦合变压器…

C++ : namespace,输入与输出,函数重载,缺省参数

一&#xff0c;命名空间(namespace) 1.1命名空间的作用与定义 我们在学习c的过程中&#xff0c;经常会碰到命名冲突的情况。就拿我们在c语言中的一个string函数来说吧&#xff1a; int strncat 0; int main() {printf("%d", strncat);return 0; } 当我们运行之后&…

大型赛事5G室内无线网络保障方案

大型活动往往才是国家综合实力的重要体现&#xff0c;其无线网络通信保障工作需融合各类新兴的5G业务应用&#xff0c;是一项技术难度高、方案复杂度高的系统工程。尤其在活动人员复杂、现场突发情况多、网络不稳定等情况下&#xff0c;如何形成一套高效、稳定的应急通信解决方…

C++入门级文章

一、一个用于查询C标准库内函数、操作符等的链接 https://legacy.cplusplus.com/reference/ 声明&#xff1a;该文档并非官方文档&#xff0c;但其具有易于查询和使用的优势&#xff0c;足够日常使用。 二、C的第一个程序 1、C语言中的语法在C中仍旧适用&#xff0c;首先我们来…

无人机无刷电机技术详解及选型

1. 技术原理 无人机无刷电机&#xff08;Brushless DC Motor, BLDC&#xff09;是现代无人机动力系统的核心部件&#xff0c;其工作原理基于电磁感应和换向技术&#xff0c;实现了无需物理接触即可持续旋转的高效率动力输出。与传统有刷电机相比&#xff0c;无刷电机通过电子换…

Java入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享

场景 作为一名Java开发者&#xff0c;势必经历过从入门到自学、从基础到进阶、从学习到强化的过程。 当经历过几年企业级开发的磨炼&#xff0c;再回头看之前的开发过程、成长阶段发现确实是走了好多的弯路。 作为一名终身学习的信奉者&#xff0c;秉承Java体系需持续学习、…

【C++高阶】:C++11的深度解析上

✨ 心似白云常自在&#xff0c;意如流水任东西 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;C学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f4…

Spring Cache框架(AOP思想)+ Redis实现数据缓存

文章目录 1 简介1.1 基本介绍1.2 为什么要用 Spring Cache&#xff1f; 2 使用方法2.1 依赖导入&#xff08;Maven&#xff09;2.2 常用注解2.3 使用步骤2.4 常用注解说明1&#xff09;EnableCaching2&#xff09;CachePut3&#xff09;Cacheable4&#xff09;CacheEvict 3 注意…

数据库相关概念大全!

一、什么是数据库&#xff1f; 1.数据库 数据库是一种更易于访问、更高效且更有条理的长期存储和处理信息的方式。 2. 优点&#xff0c;作用 数据库存储数据的规范性和系统性以及其检索数据的便捷性使其成为基于 Web 的应用程序中重要的部分。 数据库几乎可以用于所有应用程…

java中InputStream, OutputStream 的用法

java针对文件的操作有两种1.文件系统操作 File类指定的路径可以使一个不存在的路径。2&#xff0c;文件内容操作&#xff0c;流对象。 流也分为两种1)字节流&#xff08;二进制文件&#xff09;&#xff1a;以字节为基本单位读写的使用InputStream&#xff08;&#xff09;和Ou…

FFmpeg源码:av_gcd函数分析

一、引言 公约数&#xff0c;是一个能同时整除几个整数的数。如果一个整数同时是几个整数的约数&#xff0c;称这个整数为它们的“公约数”&#xff1b;公约数中最大的称为最大公约数。对任意的若干个正整数&#xff0c;1总是它们的公约数。 公约数与公倍数相反&#xff0c;就…

DB-Engines Ranking 2024年8月数据库排行

DB-Engines Ranking 2024年8月数据库排行 DB-Engines排名根据数据库管理系统的受欢迎程度进行排名。排名每月更新一次。 2024年8月&#xff0c;共有423个数据库进入排行。 排行榜 前15名趋势图 关系型数据库前 10 名 键值数据库前 10 名 文档数据库前 10 名 时序数据库前 10 …

Google引领LLM竞赛:Gemini 1.5 Pro的创新与突破

在科技领域&#xff0c;语言模型&#xff08;LLM, Large Language Model&#xff09;的发展总是备受瞩目。多年来&#xff0c;Google在这场竞赛中一直处于追赶的状态&#xff0c;但这一次&#xff0c;他们终于站在了领先的位置。Google近日发布了Gemini 1.5 Pro实验版本&#x…

Nginx进阶-常见配置

一、nginx Proxy 反向代理 1、代理原理 反向代理产生的背景&#xff1a; 在计算机世界里&#xff0c;由于单个服务器的处理客户端&#xff08;用户&#xff09;请求能力有一个极限&#xff0c;当用户的接入请求蜂拥而入时&#xff0c;会造成服务器忙不过来的局面&#xff0c…

Unity后处理(Post-processing)

Unity post-processing 就像是对图片采用滤镜一样&#xff08;如下图对比&#xff09;对当前场景显示做一定的显示处理&#xff0c;使得场景更漂亮、有趣或者有型。 视觉风格与视觉保真 游戏场景后处理能够达到所需的视觉风格&#xff08;visual style&#xff09;同时也保证视…

文件解析漏洞

IIS解析漏洞 在windows Server 2003安装iis 1.IIS6.X 1.1 目录解析 在网站下建立文件夹的名字为 .asp/.asa 的文件夹&#xff0c;其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行。 先创建一个1.asp文件夹 再创建一个1.txt 里面写 <%now()%> 2.1 畸形文件…