当前位置: 首页 > news >正文

校园课程助手【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));}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 2024上海初中生古诗文大会暑假备考:单选题真题和独家解析
  • RAG 的优化进阶与引入 Reranker
  • 频率的工程测量01 - Rif算法的构造
  • 双阈值最大最小值筛选
  • 锂离子电池健康状态预测(Part1,Python)
  • Unity Shader unity文档学习笔记(十八):unity雾效原理
  • 算法板子:树形DP、树的DFS——树的重心
  • 除湿机的标准
  • 深入探究CSRF与SSRF漏洞复现:从原理到实践
  • 智能驾驶学习笔记,第一天
  • opencascade AIS_ViewCube源码学习小方块
  • Linux中栈的大小的修改
  • vue3+element-plus实现table表格整列的拖拽
  • 函数对象/仿函数
  • 【机器学习】逻辑回归的梯度下降以及在一变量数据集、两变量数据集下探索优化的梯度下降算法
  • 网络传输文件的问题
  • 自己简单写的 事件订阅机制
  • 0基础学习移动端适配
  • android图片蒙层
  • angular2 简述
  • JavaScript设计模式与开发实践系列之策略模式
  • jquery ajax学习笔记
  • js 实现textarea输入字数提示
  • learning koa2.x
  • maven工程打包jar以及java jar命令的classpath使用
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • sessionStorage和localStorage
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 第十八天-企业应用架构模式-基本模式
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 给github项目添加CI badge
  • 构建二叉树进行数值数组的去重及优化
  • 机器学习 vs. 深度学习
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 聊聊sentinel的DegradeSlot
  • 如何进阶一名有竞争力的程序员?
  • 因为阿里,他们成了“杭漂”
  • 《码出高效》学习笔记与书中错误记录
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​虚拟化系列介绍(十)
  • # 安徽锐锋科技IDMS系统简介
  • #Datawhale X 李宏毅苹果书 AI夏令营#3.13.2局部极小值与鞍点批量和动量
  • (4)(4.6) Triducer
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (二)斐波那契Fabonacci函数
  • (规划)24届春招和25届暑假实习路线准备规划
  • (离散数学)逻辑连接词
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)http协议
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇