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 {
//        保存到mysql
        userService.save(user);
//        保存到mysql后,id已经有了,可以直接插入到ES
        esService.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 {
    @Bean
    public 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; //ID
    private 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 {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private UserService userService;

    public EsPageResult search(EsPageParams esPageParams) throws IOException {
//        1.准备request
        SearchRequest request = new SearchRequest("user");
//        2. 准备DSL
        String 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);
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

编译原理实验课

本人没咋学编译原理&#xff0c;能力有限&#xff0c;写的不好轻点喷&#xff0c;大佬路过的话&#xff0c;那你就路过就好 东大编译原理实验课原题&#xff0c;22年 1. 基本题&#xff1a;简单的扫描器设计 【问题描述】 熟悉并实现一个简单的扫描器&#xff0c;设计扫描器…

C++ | Leetcode C++题解之第49题字母异位词分组

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<string>> groupAnagrams(vector<string>& strs) {// 自定义对 array<int, 26> 类型的哈希函数auto arrayHash [fn hash<int>{}] (const array<int, 26>&…

黑马点评(十二) -- UV统计

一 . UV统计-HyperLogLog 首先我们搞懂两个概念&#xff1a; UV&#xff1a;全称Unique Visitor&#xff0c;也叫独立访客量&#xff0c;是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站&#xff0c;只记录1次。 PV&#xff1a;全称Page View&…

linux权限维持(四)

6.inetd服务后门 inetd 是一个监听外部网络请求 ( 就是一个 socket) 的系统守护进程&#xff0c;默认情况下为 13 端口。当 inetd 接收到 一个外部请求后&#xff0c;它会根据这个请求到自己的配置文件中去找到实际处理它的程序&#xff0c;然后再把接收到的 这个socket 交给那…

机器学习 -- 分类问题

场景 探讨了一个回归任务——预测住房价格&#xff0c;用到了线性回归、决策树以及随机森林等各种算法。本次中我们将把注意力转向分类系统。我们曾经对MNIST进行了分类任务&#xff0c;这次我们重新回到这里&#xff0c;细致的再来一次。 开始 获取数据 Scikit-Learn提供了…

力扣爆刷第127天之动态规划五连刷(整数拆分、一和零、背包)

力扣爆刷第127天之动态规划五连刷&#xff08;整数拆分、一和零、背包&#xff09; 文章目录 力扣爆刷第127天之动态规划五连刷&#xff08;整数拆分、一和零、背包&#xff09;关于0 1 背包问题的总结01背包遍历顺序&#xff1a;完全背包遍历顺序&#xff1a; 一、343. 整数拆…

Lock-It for Mac(应用程序加密工具)

OSXBytes Lock-It for Mac是一款功能强大的应用程序加密工具&#xff0c;专为Mac用户设计。该软件具有多种功能&#xff0c;旨在保护用户的隐私和数据安全。 Lock-It for Mac v1.3.0激活版下载 首先&#xff0c;Lock-It for Mac能够完全隐藏应用程序&#xff0c;使其不易被他人…

【Pytorch】(十四)C++ 加载TorchScript 模型

文章目录 &#xff08;十四&#xff09;C 加载TorchScript 模型Step 1: 将PyTorch模型转换为TorchScriptStep 2: 将TorchScript序列化为文件Step 3: C程序中加载TorchScript模型Step 4: C程序中运行TorchScript模型 【Pytorch】&#xff08;十三&#xff09;PyTorch模型部署: T…

平衡二叉树、红黑树、B树、B+树

Tree 1、前言2、平衡二叉树和红黑树3、B树和B树3.1、B树的构建3.2、B树和B树的区别3.3、数据的存储方式 1、前言 本文侧重在理论方面对平衡二叉树、红黑树、B树和B树的各方面性能进行比较。不涉及编程方面的实现。而关于于平衡二叉树在C中的实现&#xff0c;我的上一篇文章平衡…

Nginx基本使用 反向代理与负载均衡

什么是Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器。 其特点是占有内存少&#xff0c;并发能力强&#xff0c;nginx的并发能力在同类型的网页服务器中表现较好&#xff0c;而且几乎可以做到7*24不间断运行&#xff0c;即使运行数个月也不需要重新启动。 …

操作系统安全:Linux安全审计,Linux日志详解

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

【树莓派】yolov5 Lite,目标检测,树莓派4B,推理v5lite-e_end2end.onnx,摄像头实时目标检测

文章目录 YOLOv5 Lite: 在树莓派上轻松运行目标检测1. 环境配置2. 克隆项目3. 安装依赖项4. 下载模型权重5. 理解end2end的含义6. 示例推理7. 文件介绍8. 把文件弄到树莓派4B执行9. 进一步尝试fp16的onnx&#xff08;行不通&#xff09;10. 视频流检测 这里有大概的环境配置&am…

80个在线小游戏源码

源码简介 搭建80个在线小游戏网站源码&#xff0c;解压即可食用&#xff0c;支持在本地浏览器打开。 安装教程 纯HTML&#xff0c;直接将压缩包上传网站目录解压即可 首页截图 源码下载 80个在线小游戏源码-小8源码屋

Mac虚拟机装Windows Mac环境安装Win虚拟机教程 macbookpro安装windows虚拟机

在如今多元的数字时代&#xff0c;我们经常需要在不同的操作系统环境下进行工作和学习。而对于Mac用户来说&#xff0c;有时候需要在自己的电脑上安装Windows操作系统&#xff0c;以体验更多软件及功能&#xff0c;而在Mac安装Windows虚拟机是常用的一种操作。下面就来看看Mac虚…

前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统(LIMS)成品源码 B/S架构

前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统&#xff08;LIMS&#xff09;成品源码 B/S架构 LIMS实验室管理系统 发展历史 实验室信息管理系统(LIMS)&#xff0c;就是指通过计算机网络技术对实验的各种信息进行管理的计算机软、硬件系统。也就是将计算机网络技术与现…

新手答疑 | 零基础该怎么学习嵌入式?嵌入式Linux学习路线是什么?嵌入式开发板推荐?

很多初学者想要涉足嵌入式Linux开发领域&#xff0c;但往往在刚入门阶段&#xff0c;会因为初次接触到大量复杂的概念术语和深奥的技术文档感到压力重重&#xff0c;面对这些内容不知从何下手&#xff0c;感到十分迷茫&#xff0c;网上的内容也纷繁复杂&#xff0c;没有清晰的学…

《前端面试题》- React - 如何区分函数组件和类组件

问题 如何区分函数组件和类组件&#xff1f; 答案 可以使用instanceof 或者Component.prototype.isReactComponent。 示例 函数组件 export default function FunctionComonent() {if(FunctionComonent.prototype.isReactComponent){console.log(FunctionComonent是类组件…

白平衡简介

文章目录 白平衡的概念白平衡的调节常见的白平衡模式 白平衡的概念 白平衡是指摄影、摄像和显示技术中的一项重要概念&#xff0c;用于调节图像中的白色或中性灰色的色彩&#xff0c;使其看起来在不同光源条件下都是准确的白色或灰色。白平衡的主要目的是确保图像的色彩准确性…

C++的二叉搜索树

目录 基本概念 二叉搜索树的实现 插入结点 查找结点 删除结点 删除结点左为空 删除结点右为空 基于特殊情况的优化 删除结点左右不为空 基于特殊情况的优化 完整代码 二叉搜索树的实际应用 K和KV模型 改造二叉搜索树为为KV模型 基本概念 1、二叉搜索树又称二叉…

科技云报道:走入商业化拐点,大模型“开箱即用”或突破行业困局

科技云报道原创。 大模型加速狂飙&#xff0c;AI商业化却陷入重重困境。 一方面&#xff0c;传统企业不知道怎么将AI融入原始业务&#xff0c;另一方面&#xff0c;AI企业难以找到合适的商业化路径。 纵观海外AI玩家&#xff0c;已经有许多企业趟出了自己的商业化道路。 微…