Spring Boost + Elasticsearch 实现检索查询

需求:对“昵称”进行“全文检索查询”,对“账号”进行“精确查询”。

认识 Elasticsearch 

1. ES 的倒排索引

  1. 正向索引
    1. 对 id 进行检索速度很快。
    2. 对其他字段即使加了索引,只能满足精确查询。
    3. 模糊查询时,逐条数据扫描,判断是否符合条件。速度很慢。
  2. 倒排索引
    1. 词条(Term)+包含词条的所有文档(Document)的id,这种存储形式。

2. ES 与 mysql 的区别

3. ES 的数据结构与表结构

注:id不为long型,而是keyword。即,不参与分词。

4. ES 分词器的种类:

  1. standard
    1. 中文是逐字分词
  2. ik_smart
    1. 粗粒度。
    2. “程序员” = “程序员”
  3. ik_max_word
    1. 细粒度。
    2. “程序员” = “程序员”、“程序”、“员”

5. ES 增删改查:

  1. 指定索引库,对这个索引库进行
    1. 增:PUT
    2. 删:DELETE
    3. 改:PUT,只能新增字段,不能修改旧字段
    4. 查:GET
  2. 指定 id,对这个 id 的文档进行:
    1. 增:POST
    2. 删:DELETE
    3. 改:PUT:替换旧文档,可以实现增+改;POST:指定修改某些字段
    4. 查:GET

6. ES 查询方式:

  1. 全文检索查询
    1. 数据结构:text
    2. 利用分词器对用户输入的内容进行分词,并在倒排查询库中匹配。
    3. match_query:支持一个字段
    4. multi_match_query:支持多个字段,性能不如 match_query。
  2. 精确查询
    1. 数据结构:keyword、数值、日期、boolean
    2. term:精确查询,即等于。
    3. range:只适用于数值、日期。
  3. 其他:地理查询、符合查询等。

配置 Elasticsearch 

  1. 下载 Elasticsearch
    1. Windows10环境下安装Es7_windows安装es7-CSDN博客
    2. 7.x 和 8.x 差距比较大(8.x 版本默认有ssl 认证、用户密码登录,且在 Spring 中的操作差别有点大)。采用版本是7.12.1
    3. 有高、低版本。采用高版本。
    4. 已经不支持 java 访问 ES,而是 java request 请求的方式访问 ES。
  2. 在Spring boot 配置 ES
    1. 在 xml 中引入依赖。且需要在 properties 强制指定 ES 版本为 7.12.1。
  3. 在Spring boot 配置 FastJson
    1. 在 xml 中引入依赖。且需要指定版本为 1.2.68。1.1.x 不支持 LocalDateTime。
  4. 在Spring boot 配置 RabbitMQ
    1. 在 xml 中引入依赖。
    2. 在 yml 中配置 RabbitMQ。

实现 Elasticsearch 

1. 增删改:数据同步

  1. 如果是单体式项目:对数据库进行增删改查时,对ES也进行增删改查
  2. 如果是微服务项目:
    1. 同步调用:
      1. 服务层先操作数据库,再调用更新ES的接口。
      2. 该接口去更新ES。
      3. ES更新完成后,结果返回给接口。
      4. 接口返回给服务层。
      5. 缺点:业务耦合、耗时增加、性能下降。
    2. 异步通知
      1. 服务层操作数据库,再发布消息。
      2. ES监听并更新数据。
      3. 优点:低耦合。缺点:依赖于MQ的可靠性。
    3. 监听binlog:
      1. 服务层操作数据库。
      2. 数据库把操作记录到binlog。
      3. canal这个中间件去监听binlog,通知ES。
      4. ES更新数据。
      5. 优点:完全解除耦合度。缺点:依赖于中间件canal和mysql。mysql压力增大。

异步通知的操作:

  1. 发送MQ:
    1. 采用topic交换机。
    2. 当进行新增和修改时,发送 id 给交换机,声明“新增”的路由键(routing key)。
    3. 当进行删除时,发送 id 给交换机,并声明“删除”的路由键(routing key)。
      1. 注:不发送整个数据,而是数据的 id,以减少信息传输的数据量。
  2. 监听MQ:
    1. 监听“新增”队列的监听器:对 ES 发送新增请求。
    2. 监听“删除”队列的监听器:对 ES 发送删除请求。

单体式项目:

示例,增的同步代码,在 Controller 层:

//    增@PostMapping()public User save(@RequestBody User user) throws IOException {
//        保存到mysqluserService.save(user);
//        保存到mysql后,id已经有了,可以直接插入到ESesService.AddDocument(user);return user;}

 注:前端发来的数据 user 无 id,通过Mybatis Plus 插入到 mysql 数据库后 user 有 id,可以直接插入到 ES(不需要从 mysql 数据库查询得到 user 数据,再插入 ES)。

2. 查询 + 分页

示例,对“昵称”进行全文检索查询:

1. 创建一个配置类,注入一个 bean 方法,把向 ES 发送请求的 client 注入 IOC。

@Configuration
public class EsConfig {@Beanpublic RestHighLevelClient clien(){return new RestHighLevelClient(RestClient.builder(HttpHost.create("http://localhost:9200")));}
}

2. POJO 中封装三个类:

收到前端的类 EsPageParams

@Data
public class EsPageParams {private String key;private Integer page;private Integer size;
}

发给前端的类 EsPageResult 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class EsPageResult {private Long total;private List<User> users;
}

数据库的类 User 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {@TableId(type = IdType.AUTO)private Long id; //IDprivate String username; //用户名private String password; //密码private String niCheng; //姓名private Integer gender;private String location;private String txImageName;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;
}

(如果 ES 和 mysql 数据库不一致,还需要一个 ES 类) 

3. Controller 层:接受请求,发送给 Service 层。

4. Service 层:对 user 索引表的 niCheng 字段进行检索,检索方式是倒排索引。最终结果返回给 Controller 层。

@Service
public class EsService {@Autowiredprivate RestHighLevelClient client;@Autowiredprivate UserService userService;public EsPageResult search(EsPageParams esPageParams) throws IOException {
//        1.准备requestSearchRequest request = new SearchRequest("user");
//        2. 准备DSLString key = esPageParams.getKey();request.source().query(QueryBuilders.matchQuery("niCheng",key));int page = esPageParams.getPage();int size = esPageParams.getSize();request.source().from((page - 1) * size).size(size);
//        3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);//        4.解析响应return handleResponse(response);}private EsPageResult handleResponse(SearchResponse response){SearchHits searchHits = response.getHits();long total = searchHits.getTotalHits().value;System.out.println("共搜索到"+total+"条数据");SearchHit[] hits = searchHits.getHits();List<User> users = new ArrayList<>();for(SearchHit hit : hits){String json = hit.getSourceAsString();User user = JSON.parseObject(json, User.class);users.add(user);}return new EsPageResult(total, users);}

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

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

相关文章

VMware17Pro虚拟机安装macOS教程(超详细)

目录 1. 前言2. 下载所需文件3. 安装VMware3.1 安装3.2 启动并查看版本信息3.3 虚拟机默认位置配置 4. 安装补丁4.1 解压补丁4.2 结束VMware相关进程4.3 运行补丁包 5. 安装macOS5.1 新建虚拟机5.2 修改虚拟机配置5.3 安装操作系统5.3.1 选择 ISO 映像文件5.3.2 开启虚拟机5.2.…

重仓比特币

作者&#xff1a;Arthur Hayes Co-Founder of 100x. 编译&#xff1a;liam ccvalue (下文中表达的任何观点均为作者的个人观点&#xff0c;不应作为投资决策的依据&#xff0c;也不应被视为参与投资交易的建议或意见&#xff09;。 我们中断牛市常规节目&#xff0c;为您播报这…

SpringCloud 之 服务提供者

前提 便于理解,我修改了本地域名》这里!!! 127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com 127.0.0.1 eureka7003.com学习Rest实例之提供者 提供者模块展示 1、导入依赖 <!-- 实体类 Web--><dependency><groupId>com.jyl</groupId><…

C语言中浮点型存储方式

前言 这次是上次博客的续写哦&#xff0c;如果有小伙伴不了解&#xff0c;可以点击链接跳转 C语言中整数与浮点数在内存中的存储 我们在上次的博客中给大家留了一段代码&#xff0c;不知道大家现在有没有想明白呢&#xff0c;让我来为大家揭秘吧&#xff01;&#xff01; int m…

RakSmart美国VPS评测分析你了解多少

在当前的云计算市场中&#xff0c;RakSmart美国VPS以其出色的性能与稳定性&#xff0c;受到了广大用户的青睐。本文将对RakSmart美国VPS进行新的评测分析&#xff0c;帮助大家更好地了解这款产品。 首先&#xff0c;从性能角度来看&#xff0c;RakSmart美国VPS无疑是一款高性能…

学python的第二十一天

生成激活码&#xff0c;连接数据库&#xff0c;并保存到数据库 1&#xff0c;生成激活码 # 1 生成激活码 import random # 导入随机数模块 import os # 导入os模块 import string # 导入字符串模块def GenKey(length): # 定义生成激活码函数chars string.ascii_letters …

Linux搭建NFS服务器

什么是NFS NFS是网络文件系统&#xff08;Network File System&#xff09;的缩写&#xff0c;是一种分布式文件系统协议&#xff0c;用于在网络上共享文件和目录。NFS允许用户从一个计算机上访问另一个计算机上的文件&#xff0c;就像它们本地存在一样。这意味着&#xff0c;…

C语言学习/复习34--内存相关笔试题/C与C++的内存/柔性数组

一、动态内存管理笔试题 1.值传递 注意事项1&#xff1a;指针的地址传递需要将指针的地址用二级指针接收&#xff0c;本题属于值传递不属于地址传递 修改&#xff1a;1改为地址传递&#xff0c;2释放malloc()函数申请的空间 注意事项2&#xff1a;printf()字符串时&#xff0c;…

力扣HOT100 - 200. 岛屿数量

解题思路&#xff1a; 岛屿题目一般使用dfs。 1.判断是否越界 2.用0&#xff0c;1&#xff0c;2三个状态标识当前格子的状态&#xff08;三个状态比两个状态更清晰&#xff09; 3.向周围四个方向遍历 class Solution {public int numIslands(char[][] grid) {int cnt 0;fo…

超实用的电脑桌面便签+待办清单app

对于上班族来说&#xff0c;桌面便签加待办清单软件是提升工作效率的得力助手。想象一下&#xff0c;在繁忙的工作中&#xff0c;你能够快速记录重要事项&#xff0c;设置待办任务提醒&#xff0c;一切都能有条不紊地进行。这种便捷性&#xff0c;尤其在处理多项任务和紧急事务…

算法----BF算法KMP算法

请想象一个情景&#xff1a; 当你脑海中突然浮现出一个词&#xff0c;你该怎么去找到这个词的有关内容&#xff1f; 打开我们浏览器的搜索框&#xff0c;输入你想的这个词&#xff0c;然后点击Enter。浏览器就会自动搜索与该词匹配的内容。 这个过程实际上可以简化成以下形式…

配置有效的防爬虫技术保护网站

本文主要介绍了防爬虫的概念、目的以及一些有效的防爬虫手段。防爬虫是指网站采取各种技术手段阻止爬虫程序对其数据进行抓取的过程。为了保护网站的数据和内容的安全性&#xff0c;防止经济损失和恶意竞争&#xff0c;以及减轻服务器负载&#xff0c;网站需要采取防爬虫机制。…

人工智能_大模型042_模型微调002_模型微调代码开发_模型评估_模型checkpoint_超参数构建_训练器构建_数据规整器构建---人工智能工作笔记0177

然后我们需要使用具有GPU的服务器,来运行下面的代码: <b>注意:</b> <ul> <li>以下的代码,都不要在Jupyter笔记上直接运行,会死机!!</li> <li>请下载左边的脚本`experiments/tiny/train.py`,在实验服务器上运行。</li> 1. 导…

c++中的指针

一、指针的基本概念 指针的作用&#xff1a;可以通过指针间接访问内存 内存编号是从0开始记录的&#xff0c;一般采用16进制数字表示。可以利用指针变量保存地址。 二、指针变量的定义和使用 指针变量定义语法&#xff1a; 数据类型 * 变量名 #include<iostream> u…

g 对象:Flask 应用中的“临时口袋”

文章目录 g对象的理解Flask 中的 g 对象g 对象的特点:使用 g 对象: 示例 g对象的理解 想象一下&#xff0c;你在逛超市。你需要一个购物篮来装你挑选的商品。这个购物篮就像 Flask 应用中的 g 对象&#xff0c;它是一个临时存放东西的地方&#xff0c;方便你在购物过程中随时取…

Mybatis之if标签判断boolean值

文章目录 一、普通的字符串类型判断空逻辑二、Boolean类型判断 一、普通的字符串类型判断空逻辑 <if test"query.activity ! null and query.activity ! ">AND extra.activity #{query.activity}</if>二、Boolean类型判断 <if test"!query.ori…

多组学+机器学习+膀胱癌+分型+建模

这是一个基于多组学机器学习的分型建模文章&#xff0c;这里我们大概介绍一下&#xff0c;这篇文章做了啥 一、研究背景 1、尿路上皮癌是高度恶性的肿瘤&#xff0c;预后差&#xff0c;死亡率高 2、没有明显有效的治疗方法&#xff0c;多数患者在免疫治疗中无法受益&#xf…

selenium显式等待

selenium显示等待 确保页面元素在特定条件下加载完毕后再执行后续操作。显示等待可以通过WebDriverWait类和ExpectedConditions类来实现。通过使用显示等待&#xff0c;可以避免在页面元素还未加载完毕时就进行操作&#xff0c;从而提高测试的稳定性和可靠性。 # 导包 from s…

SpringBoot Filter过滤器的使用篇

Filter生命周期 程序启动调用Filter的init()方法(永远只调用一次)&#xff1b;程序停止调用Filter的destroy()方法(永远只调用一次)&#xff1b;doFilter()方法每次的访问请求如果符合拦截条件都会调用(程序第一次运行&#xff0c;会在servlet调用init()方法以后调用&#xff…

【基于YOLOv8的教室人脸识别 附源码 数据集】

基于YOLOv8的教室人脸识别 附源码 数据集 在当今数字化迅速发展的教育领域中&#xff0c;人脸识别技术已成为提高校园安全和教学效率的关键工具。本文将详细介绍基于最新YOLOv8算法的教室人脸识别系统&#xff0c;这一系统不仅能够实时准确地识别学生和教职工的面部特征&#…