当前位置: 首页 > 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));}
}
http://www.lryc.cn/news/413972.html

相关文章:

  • 经典运维面试题
  • 别再盲目推广了!Xinstall助你开启App线下推广新篇章
  • 大厂linux面试题攻略五之数据库管理
  • 【pytorch】模型集成
  • 初识集合和数据结构
  • cocos creator 3.x中动态加载 resources 文件夹下的图片时提示找不到
  • 第九十八周周报
  • 程序员找工作之数据结构面试题总结分析
  • 设置provider解决maven找不到JUnit 5测试样例
  • php反序列化靶机serial实战
  • 类型推断技术及仓颉语言实践
  • 职场生存秘籍:16条黄金法则
  • Flask 介绍
  • JAVA基础知识点3 (String 和 StringBuffer 以及 StringBuilder 的特点以及区别)
  • 2024年8月AI内容生成技术的现状与未来:从文生文到跨模态交互的全景分析
  • File 34
  • AI全知道-Embedding model中的Vector知识点
  • Qt 学习第四天:信号和槽机制(核心特征)
  • 跳跃游戏Ⅱ C++简单代码
  • Gitlab中access token 和Deploy token的区别
  • 【多线程】线程的五种创建方法
  • 关闭窗口工具类 - C#小函数类推荐
  • Xilinx FPGA 原语解析(一):IBUFDS_GTE3 差分时钟输入缓冲器
  • 力扣SQL50 患某种疾病的患者 正则表达式
  • k8s集群的资源发布方式(滚动/蓝绿/灰度发布)及声明式管理方法
  • SwiftUI 中掌握 ScrollView 的使用:滚动可见性
  • 中药养发护发
  • Java面试题-集合类
  • 【Vue3】组件通信之v-model
  • 【Golang 面试 - 进阶题】每日 3 题(二)