Elasticsearch 学习+SpringBoot实战教程(三)

需要学习基础的可参照这两文章

Elasticsearch 学习+SpringBoot实战教程(一)

Elasticsearch 学习+SpringBoot实战教程(一)_桂亭亭的博客-CSDN博客

Elasticsearch 学习+SpringBoot实战教程(二)  

Elasticsearch 学习+SpringBoot实战教程(二)_桂亭亭的博客-CSDN博客

前言: 经过了前面2课的学习我们已经大致明白了ES怎么使用,包括原生语句,javaapi等等,现在我们要在业务中使用了,

所以我们选择spring-data作为我们的ORM框架,快速开发代码。

同时需要给规范化操作

目录

0 前辈动作

1 Springboot项目引入依赖

2 建立目录与文件

3 配置文件

 4 实体类

1 使用ElasticsearchOperations的方式

新增文档

更新文档 

删除文档

查询所有

查询指定id

分页+指定条件+高亮显示+排序+过滤结果

2 使用RestHighLevelClient的方式

精确查询

分页查询

字符匹配AND精准查询

​编辑字符匹配OR精准查询

模糊查询


0 前置动作

1 Springboot项目引入依赖

注意你的ES版本号

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.20</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.10.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.elasticsearch</groupId>
                    <artifactId>elasticsearch</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.10.1</version>
        </dependency>

2 建立目录与文件

 

3 配置文件

spring:
  elasticsearch:
    uris: localhost:9200
    connection-timeout: 3000
    socket-timeout: 5000

 4 实体类

package com.example.eslearn.entity;

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.io.Serializable;

/**
 *  Document:  将这个类对象转为 es 中一条文档进行录入
 * indexName: 用来指定文档的索引名称
 * createIndex: 用来指定是否创建索引,默认为false
 */
@Document(indexName = "user", createIndex = true)
public class UserDocument implements Serializable {
    @Id // 用来将放入对象id值作为文档_id进行映射
    private String id;
    @Field(type = FieldType.Keyword)    // 字段映射类型
    private String name;
    private String sex;
    private Integer age;
    @Field(type = FieldType.Text)    // 字段映射类型

    private String city;

 

1 使用ElasticsearchOperations的方式

优点:更想我们的springdata的使用风格,简单,快捷,个人使用

新增文档

    private final ElasticsearchOperations ESO;
    // set方法注入
    @Autowired
    public CRUDService2(ElasticsearchOperations elasticsearchOperations) {
        this.ESO = elasticsearchOperations;
    }
    // 新增文档
    public String save() {
        UserDocument user = new UserDocument();
        user.setName("说不定看见的");
        user.setCity("北京 上海 西安");
        user.setAge(22);
        user.setSex("男");
        UserDocument save = ESO.save(user);
        System.out.println(save);
        return JSON.toJSONString(save);
    }

 使用可视化软件查询,得到下面的结果  

 

更新文档 

    // 更新文档
    public String update() {
        UserDocument user = new UserDocument();
        user.setId("W7w2HYcB32f1ZLmxRwzw");
        user.setName("说快来打见的");
        user.setCity("北京 上海 西安");
        user.setAge(21);
        user.setSex("女");
        UserDocument save = ESO.save(user);
        System.out.println(save);
        return JSON.toJSONString(save);
    }

 

 

 

删除文档

    // 删除
    public String delete(){
        UserDocument userDocument = new UserDocument();
        userDocument.setId("8966e506-1763-4d4b-bf1c-4f5d9bd9b052");
        return ESO.delete(userDocument);
    }

 

查询所有

    // 查询所有
    public String findAll(){
        //查询所有
        SearchHits<UserDocument> search = ESO.search(Query.findAll(), UserDocument.class);
        for (SearchHit<UserDocument> uc : search) {
            System.out.println(uc.getContent());
        }
        return JSON.toJSONString(search);
    }

 

查询指定id

    // 根据id查询文档
    public String getById(){
        UserDocument userDocument = ESO.get("W7w2HYcB32f1ZLmxRwzw", UserDocument.class);
        return JSON.toJSONString(userDocument);
    }

分页+指定条件+高亮显示+排序+过滤结果

服务层

 //大杂烩,一次学会
    public String findSource(){
        //查询条件构建
        MatchQueryBuilder mp=new MatchQueryBuilder("name","妲己");

        //排序构建
        FieldSortBuilder f = new FieldSortBuilder("age");
        //分页构建
        Pageable page= PageRequest.of(0,5);
        // 高亮构建
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .preTags("<span style='color:yellow'>")
                .postTags("</span>")
                .field("name");
        //结果过滤构建,相当于返回那些字段
        FetchSourceFilter filter = new FetchSourceFilter(new String[]{"name", "city"}, null);
        //查询语句构建
        NativeSearchQueryBuilder  query = new NativeSearchQueryBuilder()
                .withQuery(mp)
                .withSorts(f)
                .withPageable(page)
                .withHighlightBuilder(highlightBuilder)
                .withSourceFilter(filter);
        //执行查询
        SearchHits<UserDocument> search = ESO.search(query.build(), UserDocument.class);
        return JSON.toJSONString(search);
    }

控制器

    @GetMapping("/findSource")
    private String findSource(){
        return sv.findSource();
    }

 

 

 

2 使用RestHighLevelClient的方式

优点:安全,企业级常用

精确查询

对应的原生查询语句

注意这里的term就是精准查询到 关键字

GET user/_search
{
  "query": {
    "term": {
      "city": "上海"
    }
    
  }
}

服务层 

    // 文档搜索
    public String searchDocument(String indexName,String city){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        //3 构建搜索内容
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("city", city);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(termQueryBuilder);
        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits().getHits());
    }

控制器


    @GetMapping("/searchUserByCity")
    public String searchUserByCity() throws IOException {
        return service.searchDocument("user","上海");
    }

访问链接localhost:8080/searchUserByCity

分页查询

GET user/_search
{
  "query": {
    "term": {
      "city": "上海"
    }
    
  },
  "from":0,
  "size":5
}

服务层

  // 文档搜索--分页查询
    public String searchDocument2(String indexName,String city){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        //3 构建搜索内容
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //拿到前5条数据
        searchSourceBuilder
                .query(QueryBuilders.termQuery("city", city))
                .from(0)
                .size(5);

        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits().getHits());
    }

控制层 

    @GetMapping("/searchUserByCity2")
    public String searchUserByCity2() throws IOException {
        return service.searchDocument2("user","上海");
    }

访问localhost:8080/searchUserByCity2

字符匹配AND精准查询

term 与matchphrase的比较 term用于精确查找有点像 mysql里面的"=" match是先将查询关键字分词然后再进行查找。term一般用在keywokrd类型的字段上进行精确查找。

注意这里的bool,表示使用布尔查询,其中的must是相当于SQL语句中的and的意思。

所以就是查找name中包含“妲己”并且年龄为22岁的信息,请注意不能写成"妲",因为我们在新建文档的时候是这样新建的“妲己”,那么我们如果匹配“妲”就会匹配不到,加入这样写就可以匹配到了“妲 己”,请注意空格,这是分词的依据之一

ES查询语句。

GET user/_search
{
  "query": {
    "bool":{
      "must": [
        {
          "match_phrase": {
            "name": "妲己"
          }
        },
         {
          "term": {
            "age": "32"
          }
        }
      ]
    }
    
  },
  "from":0,
  "size":10
}

服务层

// 文档分词搜索+精确查询
    public String searchDocument3(String indexName,String name,Integer age){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //3 构建复杂的查询语句
        BoolQueryBuilder bq=QueryBuilders
                .boolQuery()
                //分词匹配
                .must(QueryBuilders.matchPhraseQuery("name",name))
                //精确匹配
                .must(QueryBuilders.matchQuery("age",age));
        //4 填充搜索语句
        searchSourceBuilder
                .query(bq)
                .from(0)
                .size(5);

        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits());
    }

控制层

    @GetMapping("/searchUser3")
    public String searchUser3() throws IOException {
        return service.searchDocument3("user","妲己",32);
    }

字符匹配OR精准查询

 原始查询语句

GET user/_search
{
  "query": {
    "bool":{
      "should": [
        {
          "match_phrase": {
            "name": "妲己"
          }
        },
         {
          "term": {
            "age": "32"
          }
        }
      ]
    }
    
  },
  "from":0,
  "size":10
}

服务层

    // 文档分词搜索OR精确查询
    public String searchDocument4(String indexName,String name,Integer age){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //3 构建复杂的查询语句
        BoolQueryBuilder bq=QueryBuilders
                .boolQuery()
                //分词匹配
                .should(QueryBuilders.matchPhraseQuery("name",name))
                //精确匹配
                .should(QueryBuilders.matchQuery("age",age));
        //4 填充搜索语句
        searchSourceBuilder
                .query(bq)
                .from(0)
                .size(5);

        //4 填充搜索内容
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits());
    }

控制层 

    @GetMapping("/searchUser4")
    public String searchUser4() throws IOException {
        return service.searchDocument4("user","妲己",22);
    }

 结果

模糊查询

原始语句

GET user/_search
{
  "query": {
    "wildcard": {
      "city": {
        "value": "上*"
      }
    }
  }
}
    // 文档模糊查询
    public String searchDocument5(String indexName,String city){
        //2 构建搜索请求
        SearchRequest searchRequest = new SearchRequest().indices(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //3 构建模糊查询的语句
        WildcardQueryBuilder bq=QueryBuilders
                .wildcardQuery("city",city);
        //4 填充搜索语句
        searchSourceBuilder
                .query(bq);

        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            //5 执行搜索操作
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //6 返回值
        return JSON.toJSONString(searchResponse.getHits());
    }
    @GetMapping("/searchUser5")
    public String searchUser5() throws IOException {
        return service.searchDocument5("user","上*");
    }

结果 

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

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

相关文章

第十四届蓝桥杯三月真题刷题训练——第 23 天

目录 第 1 题&#xff1a;长草 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码&#xff1a; 思路&#xff1a; 第 2 题&#xff1a;蓝肽子序列_LCS_最长公共子序列dp问题 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码&#xff1a; 思路&am…

Spring源码面试最难问题——循环依赖

前言 问&#xff1a;Spring 如何解决循环依赖&#xff1f; 答&#xff1a;Spring 通过提前曝光机制&#xff0c;利用三级缓存解决循环依赖&#xff08;这原理还是挺简单的&#xff0c;参考&#xff1a;三级缓存、图解循环依赖原理&#xff09; 再问&#xff1a;Spring 通过提前…

【前沿技术】问答pk【ChatGPT Vs Notion AI Vs BAT AI 】

目录 写在前面 问题&#xff1a; 1 ChatGPT 1.1 截图 ​1.2 文字版 2 Notion AI 2.1 截图 2.2 文字版 3 BAT AI 3.1 截图 3.2 文字版 总结 序言 所有幸运和巧合的事&#xff0c;要么是上天注定&#xff0c;要么是一个人偷偷的在努力。 突发奇想&#xff0c;问三个…

③【Java组】蓝桥杯省赛真题 持续更新中...

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 蓝桥杯真题--持续更新中...一、错误票据题目描…

CCF-CSP认证 202303 500分题解

202303-1 田地丈量&#xff08;矩阵面积交&#xff09; 矩阵面积交x轴线段交长度*y轴线段交长度 线段交长度&#xff0c;相交的时候是min右端点-max左端点&#xff0c;不相交的时候是0 #include<bits/stdc.h> using namespace std; int n,a,b,ans,x,y,x2,y2; int f(in…

用CSS3画了一只猫

感觉我写得技术含量不高&#xff0c;全都是用绝对定位写的&#xff0c;一定会有更好的&#xff0c;代码量更少的做法吧 <!DOCTYPE html> <html> <head><title>Cute Cat</title><style type"text/css">*{box-sizing: border-box…

100天精通Python(可视化篇)——第81天:matplotlib绘制不同种类炫酷饼图参数说明+代码实战(自定义、百分比、多个子图、圆环、嵌套饼图)

文章目录专栏导读0. 前言1. 参数说明2. 普通饼图3. 百分比饼图4. 突出某一块的饼图5. 自定义颜色的饼图6. 多个子图7. 圆环饼图8. 圆环分离饼图9. 饼图圆环图组合10. 多层圆环饼图专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业》&#xff1a…

【VScode】远程连接Linux

目录标题1. 安装扩展插件2. 在Linux上操作3. 确定Linux的IP地址4. 远程连接到Linux5. 实现免密码登录使用 VScode 远程编程与调试的时有会用到插件 Remote Development&#xff0c;使用这个插件可以在很多情况下代替 vim 直接远程修改与调试服务器上的代码&#xff0c;同时具备…

超详细讲解C语言文件操作!!

超详细讲解C语言文件操作&#xff01;&#xff01;什么是文件文件名文件的打开和关闭文件指针文件的打开和关闭文件的顺序读写文件的随机读写fseekftellrewind文本文件和二进制文件文件读取结束的判定文件缓冲区什么是文件 磁盘上的文件是文件。但是在程序设计中&#xff0c;我…

Python | 蓝桥杯系列文章总结+经典例题重做

欢迎交流学习~~ 专栏&#xff1a; 蓝桥杯Python组刷题日寄 从 4 个月前开始写蓝桥杯系列&#xff0c;到目前为止一共是 19 篇&#xff0c;其中&#xff1a;入门篇 5 篇&#xff0c;简单篇 8 篇&#xff0c;进阶篇 6 篇。 这篇文章主要是为了为先前内容进行总结&#xff0c;并对…

蓝桥杯冲刺 - Lastweek - 你离省一仅剩一步之遥!!!(掌握【DP】冲刺国赛)

文章目录&#x1f4ac;前言&#x1f3af;week3&#x1f332;day10-1背包完全背包多重背包多重背包 II分组背包&#x1f332;day2数字三角形 - 线性DP1015. 摘花生 - 数字三角形&#x1f332;day3最长上升子序列 - 线性DP1017. 怪盗基德的滑翔翼 - LIS1014.登山 - LIS最长公共子…

【JaveEE】多线程之阻塞队列(BlockingQueue)

目录 1.了解阻塞队列 2.生产者消费者模型又是什么&#xff1f; 2.1生产者消费者模型的优点 2.1.1降低服务器与服务器之间耦合度 2.1.2“削峰填谷”平衡消费者和生产的处理能力 3.标准库中的阻塞队列&#xff08;BlockingQueue&#xff09; 3.1基于标准库&#xff08;Bloc…

笔记本只使用Linux是什么体验?

个人主页&#xff1a;董哥聊技术我是董哥&#xff0c;嵌入式领域新星创作者创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01;近期&#xff0c;也有朋友问我&#xff0c;笔记本只安装Linux怎么样&#xff0c;刚好我也借此来表达一下我的感受…

数据结构MySQL —— 索引

目录 一、索引概述 二、索引结构 三、索引分类 四、索引语法 五、SQL性能分析 1. 查看执行频次 2. 慢查询日志 3. show profiles指令 4. explain执行计划 六、索引使用规则 1. 验证索引效率 2. 最左前缀法则 3. 范围查询 4. 索引失效情况 5. SQL提示 6. …

【C++】AVL树

文章目录一、什么是 AVL 树二、AVL 树的节点结构三、AVL 树的插入四、AVL 树的旋转1、左单旋2、右单旋3、左右双旋4、右左双旋5、总结五、VAL 树的验证六、AVL 树的删除七、AVL 树的性能八、AVL 树的代码实现一、什么是 AVL 树 我们在前面学习二叉搜索树时提到&#xff0c;二叉…

【linux】深入了解TCP与UDP

认识端口号 端口号(port)是传输层协议的内容. 端口号是一个2字节16位的整数; 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理; IP地址 端口号能够标识网络上的某一台主机的某一个进程; 一个端口号只能被一个进程占用理解 "端口号" 和…

【Java 并发编程】一文详解 Java 中有几种创建线程的方式

Java 中有几种创建线程的方式?1. Java 程序天然就是多线程的2. 线程的启动与终止2.1 线程的启动&#xff08;1&#xff09;继承 Thread 类&#xff0c;重写 run() 方法&#xff08;2&#xff09;实现 Runnable 接口&#xff0c;重写 run() 方法&#xff08;3&#xff09;Threa…

jwt 学习笔记

概述 JWT&#xff0c;Java Web Token&#xff0c;通过 JSON 形式作为 Web 应用中的令牌&#xff0c;用于在各方之间安全地将信息作为 JSON 对象传输&#xff0c;在数据传输过程中还可以完成数据加密、签名等相关处理 JWT 的作用如下&#xff1a; 授权&#xff1a;一旦用户登…

初识操作系统

目录 1.操作系统是什么 2.为什么要有操作系统 3.操作系统的相关关系 1.驱动程序 2.系统调用接口 3.用户调用接口 4.用户程序 4.用具体的例子理解操作系统 1.操作系统是什么 &#xff08;1&#xff09;操作系统是一组管理计算机硬件与软件资源的计算机软件程序 。 &#xff08;…

STM32入门教程课程简介(B站江科大自化协学习记录)

课程简介 STM32最小系统板面包板硬件平台 硬件设备 STM32面包板入门套件 Windows电脑 万用表、示波器、镊子、剪刀等 软件介绍 Keil MDK 5.24.1 是一款嵌入式软件开发工具&#xff0c;它提供了一个完整的开发环境&#xff0c;包括编译器、调试器和仿真器。它支持各种微控制…