当前位置: 首页 > 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));}
}

相关文章:

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

本节将介绍本项目的查询模块&#xff0c;使用Elasticsearch又不是查询接口&#xff0c;具体流程如图所示&#xff08;如果不了解Elasticsearch可以使用sql语句进行查询&#xff09;&#xff1a; 这里是两种方法的异同点&#xff1a; Mysql&#xff1a;擅长事务类型操作&#…...

经典运维面试题

1、Linux常见的日志文件都有哪些&#xff0c;各自的用途&#xff1f;日志轮询配置文件在哪里&#xff1f;欢迎界面配置文件在哪里&#xff1f; /var/log/messages #内核及公共消息日志/var/log/cron #计划任务日志/var/log/dmesg #系统引导日志/var/log/malilog #邮件系…...

别再盲目推广了!Xinstall助你开启App线下推广新篇章

在这个数字化飞速发展的时代&#xff0c;App已经成为我们生活中不可或缺的一部分。然而&#xff0c;App市场的竞争也日益激烈&#xff0c;如何让你的App在众多竞争者中脱颖而出&#xff0c;成为每个推广者必须面对的问题。今天&#xff0c;就让我们一起探讨一下App线下推广的痛…...

大厂linux面试题攻略五之数据库管理

一、数据库管理-MySQL语句 0.MySQL基本语句&#xff1a; 1.SQL语句-增 创建xxx用户&#xff1a; mysql>create user xxx % indentified by 123456; xxx表示用户名 %b表示该用户用来连接数据库的方式&#xff08;远程或本地连接&#xff09; indentified by 123456设置密码…...

【pytorch】模型集成

在集成学习中&#xff0c;我们会训练多个模型&#xff08;通常称为「弱学习器」&#xff09;解决相同的问题&#xff0c;并将它们结合起来以获得更好的结果。最重要的假设是&#xff1a;当弱模型被正确组合时&#xff0c;我们可以得到更精确和/或更鲁棒的模型。 常用的模型集成…...

初识集合和数据结构

目录 初识集合框架数据结构基本概念和术语数据数据元素数据项数据对象前四者的关系数据结构逻辑结构和物理结构逻辑结构物理结构 算法算法设计要求 初识集合框架 Java的集合框架也可被称为容器&#xff0c;是定义在Java.util包下的一些接口和实现类。其就是将多个元素存储到一…...

cocos creator 3.x中动态加载 resources 文件夹下的图片时提示找不到

文件目录如下 类型为spriteFrame 代码案例 图片设置为 sprite-frame、texture 或其他图片类型后&#xff0c;将会在 资源管理器 中生成一个对应类型的资源。但如果直接加载 equipments/testea&#xff0c;得到的类型将会是 ImageAsset&#xff0c;必须指定路径到具体的子资源…...

第九十八周周报

学习时间&#xff1a; 2024.7.27-204.8.3 学习产出&#xff1a; 这周主要在按照审稿人的意见修改论文&#xff0c;由于有个模型保存的文件找不到了&#xff0c;所以重新训练花了点时间&#xff0c;目前已经把修改后的论文和cover letter发给杨老师了。...

程序员找工作之数据结构面试题总结分析

文章目录 1. 数据结构的基本概念与分类2. 数据结构的存储与表示3. 数据元素的存储与关系4. 存储结构的选择与考量5. 特定数据结构的定义与特性6. 数据结构操作与应用7. 数组与存储8. 特定数据结构的存储与访问 程序员在找工作面试中&#xff0c;数据结构方面可能会被问到的问题…...

设置provider解决maven找不到JUnit 5测试样例

问题描述 尝试复现一个用大模型生成测试样例的工作&#xff0c;但使用maven生成的JUnit 5测试样例死活不执行。又不想用命令行运行&#xff0c;因此进行排查 基本知识 <dependencies> junit-jupiter-api JUnit 5写代码时调用的库 junit-jupyter-engine 运行JUnit 5测…...

php反序列化靶机serial实战

扫描ip,找到靶机ip后进入 他说这是cookie的测试网页&#xff0c;我们抓个包&#xff0c;得到cookie值 base64解码 扫描一下靶机ip的目录 发现http://192.168.88.153/backup/&#xff0c;访问 下载一下发现是他的网页源码 通过代码审计&#xff0c;发现 通过代码审计得知&…...

类型推断技术及仓颉语言实践

史磊 仓颉语言类型推断技术专家 一、一种看待类型系统的方式 一门编程语言一定得包含类型系统吗&#xff1f; 这个问题今天看来可能显而易见&#xff0c;一个程序没有类型的话还能算是个完整、正确的程序吗&#xff1f;但是其实关于类型系统的作用&#xff0c;一直是存在两种…...

职场生存秘籍:16条黄金法则

作者简介&#xff1a;一名计算机萌新、前来进行学习VUE,让我们一起进步吧。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;我叫于豆豆吖的主页 写在前面 在这个瞬息万变的时代&#xff0c;职场不仅是实现个人价值与梦想的舞台&#xff0c;更是一…...

Flask 介绍

Flask 介绍 为什么要学 Flask框架对比设计哲学功能特点适用场景学习曲线总结 Flask 的特点Flask 常用扩展包Flask 的基本组件Flask 的应用场景官方文档官方文档链接文档内容概述学习建议 Flask 是一个使用 Python 编写的轻量级 Web 应用框架。它旨在让 Web 开发变得快速、简单且…...

JAVA基础知识点3 (String 和 StringBuffer 以及 StringBuilder 的特点以及区别)

1&#xff0c;String 和 StringBuffer 以及 StringBuilder 的特点 &#xff08;1&#xff09;String的特点&#xff1a;String是final修饰的字符序列是不可改变的&#xff0c; 是字符串常量&#xff0c;一旦初始化就不可以被更改,因此是线程安全的 因为是常量每次对其操作都会…...

2024年8月AI内容生成技术的现状与未来:从文生文到跨模态交互的全景分析

2024年8月AI内容生成技术的现状与未来&#xff1a;从文生文到跨模态交互的全景分析 大家好&#xff0c;我是猫头虎&#xff01;&#x1f680; 随着AI在内容生成领域的爆发式发展&#xff0c;从2022年末开始&#xff0c;AI生成技术已经走过了文生文&#xff08;AIGC&#xff09…...

File 34

package File;import java.awt.*; import java.io.File;public class file1 {public static void main(String[] args) {//创建FILE对象&#xff0c;指代某个具体的文件//路径分隔符File f1new File("C:/Users/SUI/Desktop/kaishi/nih.txt");// File f1new File(&quo…...

AI全知道-Embedding model中的Vector知识点

在嵌入模型(Embedding Model)中,向量(Vector)是核心概念之一。向量表示法不仅是数学中的基本工具,也是机器学习和深度学习中处理高维数据的关键手段。本文将深入探讨向量在嵌入模型中的作用、表示方法、计算和应用等知识点。 一、向量的基本概念 向量是一个具有方向和大…...

Qt 学习第四天:信号和槽机制(核心特征)

信号和槽的简介 信号和插槽用于对象之间的通信。信号和插槽机制是Qt的核心特征&#xff0c;可能是不同的部分大部分来自其他框架提供的特性。信号和槽是由Qt的元对象系统实现的。介绍&#xff08;来自Qt帮助文档Signals & Slots&#xff09; 在GUI编程中&#xff0c;当我们…...

跳跃游戏Ⅱ C++简单代码

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…...

AI图像编辑中的性别擦除现象与视觉公平性测试

1. 项目概述&#xff1a;当AI“擦除”男性面孔时&#xff0c;我们到底在测试什么&#xff1f;“AI Erases Men Too: A Visual Test of Bias Across Four Leading Tools”——这个标题乍看像一则科技媒体的警示快讯&#xff0c;但背后是一次扎实、可复现、有明确方法论支撑的视觉…...

别再死记硬背了!用Python手把手拆解卡尔曼滤波的‘预测-更新’循环

别再死记硬背了&#xff01;用Python手把手拆解卡尔曼滤波的‘预测-更新’循环 卡尔曼滤波在工程领域就像一位隐形的魔术师——它能从充满噪声的传感器数据中提取出真实信号。但第一次接触那些矩阵方程时&#xff0c;多数人都会陷入"每个字母都认识&#xff0c;连起来完全…...

结构化生成式AI驱动材料设计:从生物启发到实验验证的完整实践

1. 项目概述&#xff1a;当AI遇见材料科学&#xff0c;一场设计范式的革命“AI驱动材料科学”这个标题&#xff0c;听起来宏大又前沿&#xff0c;但它的内核其实非常具体和务实。作为一名在材料计算与实验交叉领域摸爬滚打了十多年的从业者&#xff0c;我亲眼见证了这场变革从概…...

智能体元观察者技能:提升AI自主决策的监控与反思能力

1. 项目概述&#xff1a;一个面向智能体的“元观察者”技能最近在折腾智能体&#xff08;Agent&#xff09;开发&#xff0c;特别是那些需要长期运行、具备一定自主决策能力的应用时&#xff0c;发现一个普遍痛点&#xff1a;智能体在执行任务时&#xff0c;往往“埋头苦干”&a…...

终极开源语音AI工具包:Sherpa-Onnx一站式解决方案

终极开源语音AI工具包&#xff1a;Sherpa-Onnx一站式解决方案 【免费下载链接】sherpa-onnx Speech-to-text, text-to-speech, speaker diarization, speech enhancement, source separation, and VAD using next-gen Kaldi with onnxruntime without Internet connection. Sup…...

图解人工智能(8)图灵测试作为智能与否的标准

有人不同意将图灵测试作为智能与否的标准。他们认为&#xff0c;就算机器表现得和人一样&#xff0c;也不能说机器拥有了智能&#xff0c;因为它只是一堆电路&#xff0c;和人的思维方式完全不同。你是否赞同这种说法&#xff1f;说说你赞同或反对的理由。开放讨论题。有几种观…...

Cadence 17.4 保姆级教程:从DRC检查到Gerber输出的完整避坑指南

Cadence 17.4 终极避坑指南&#xff1a;从DRC检查到Gerber输出的全流程实战 第一次使用Cadence Allegro 17.4导出Gerber文件时&#xff0c;那种如履薄冰的感觉至今记忆犹新。记得去年为TMC2300电机驱动模块导出生产文件时&#xff0c;因为一个简单的单位设置错误&#xff0c;导…...

实测MPU6050低功耗电流:从Sleep到Cycle模式,不同唤醒频率下功耗到底差多少?

MPU6050低功耗模式实测&#xff1a;从微安级电流到唤醒策略的硬件优化指南 当你的智能手环在手腕上安静沉睡时&#xff0c;MPU6050这颗运动传感器正在以微安级的电流维持着生命体征——这不是魔法&#xff0c;而是现代嵌入式设计中精妙的低功耗艺术。作为硬件工程师&#xff0c…...

别再傻傻分不清!Ansys Workbench三大建模界面(SCDM/DM/Mechanical)保姆级对比与选用指南

Ansys Workbench三大建模界面深度解析&#xff1a;如何根据项目需求选择最佳工具 在工程仿真领域&#xff0c;Ansys Workbench作为行业标杆软件套件&#xff0c;其内置的三大建模界面——SpaceClaim&#xff08;SCDM&#xff09;、DesignModeler&#xff08;DM&#xff09;和Me…...

如何快速掌握WindowResizer:终极窗口强制调整工具完整指南

如何快速掌握WindowResizer&#xff1a;终极窗口强制调整工具完整指南 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 还在为那些顽固的固定尺寸窗口而烦恼吗&#xff1f;WindowRe…...