SpringBoot集成 ElasticSearch

news2024/9/29 9:35:41

Spring Boot 集成 ElasticSearch

对于ElasticSearch比较陌生的小伙伴可以先看看ElasticSearch的概述ElasticSearch安装、启动、操作及概念简介
好的开始啦~

1、基础操作

1.1、导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  • 新版本配置方式(推荐使用)

    新的配置方式使用的是 High Level REST Client 的方式来替代之前的 Transport Client 方式,使用的是 HTTP 请求,和 Kibana 一样使用的是 Elasticsearch 的 9200 端口。

1.2、自定义配置类

这种配置方案中,你使用的不是配置文件,而是自定义配置类:

/**
 * 你也可以不继承 AbstractElasticsearchConfiguration 类,而将 ESConfig 写成一般的配置类的型式。
 * 不过继承 AbstractElasticsearchConfiguration 好处在于,它已经帮我们配置好了 elasticsearchTemplate 直接使用。
 */
@Configuration
public class ESConfig extends AbstractElasticsearchConfiguration {

    @Override
    public RestHighLevelClient elasticsearchClient() {
        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
            .connectedTo("localhost:9200")
            .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

1.3、实体类

Elasticsearch 中的 PO 类:

@Document(indexName = "books",shards = 1,replicas = 0)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ESBook {

    @Id
    @Field(type = FieldType.Keyword)
    private String id;

    @Field(type = FieldType.Text)
    private String title;

    @Field(type = FieldType.Keyword)
    private String language;

    @Field(type = FieldType.Keyword)
    private String author;

    @Field(type = FieldType.Float)
    private Float price;

    @Field(type = FieldType.Text)
    private String description;
}

  • @Document :注解会对实体中的所有属性建立索引;
  • indexName = “books” :表示创建一个名称为 “books” 的索引;
  • shards = 1 : 表示只使用一个分片;
  • replicas = 0 : 表示不使用复制备份;
  • @Field(type = FieldType.Keyword) : 用以指定字段的数据类型。

2、 创建操作的 Repository

@Repository
//看实体类Id索引是什么类型 我这里是String
public interface ESBookRepstitory extends ElasticsearchRepository<ESBook, String> {
    
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5wSibzg8-1681375145182)(assets\spring-boot-es-02.png)]

我们自定义的 CustomerRepository 接口,从它的祖先们那里继承了大量的现成的方法,除此之外,它还可以按 spring data 的规则定义特定的方法。

3、 测试 CustomerRepository

// 创建索引
@Test
public void indexList() {
   System.out.println("创建索引");
}
// 删除索引
@Test
public void indexList() {
	restTemplate.indexOps(IndexCoordinates.of("books")).delete();
    System.out.println("删除索引");
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2HQkNX8j-1681375145182)(C:\Users\lps\AppData\Roaming\Typora\typora-user-images\image-20230413111252346.png)]

4.、CRUD操作

4.1、批量新增

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xP3YE5M7-1681375145183)(C:\Users\lps\AppData\Roaming\Typora\typora-user-images\image-20230413142657737.png)]

   @Autowired
   private ESBookRepstitory  bookByESRepstitory;
  @Test
    public void indexList() {
        List<ESBook> lists = new ArrayList<>();
        lists.add(new ESBook("1", "Java 程序设计", "汉语", "盖伦",
                18.88F, "哈哈嗨"));
        lists.add(new ESBook("2", "Python程序设计", "英语", "赵信",
                66.88F, "陷阵之至有死无生"));
        lists.add(new ESBook("3", "PHP 程序设计", "俄语", "宝石",
                88.88F, "我曾踏足山巅,也曾跌入低谷"));
        bookByESRepstitory.saveAll(lists);
    }

id重复的话 会覆盖之前的~~~

4.2、修改

修改和新增是同一个接口,区分的依据就是id,这一点跟我们在页面发起PUT请求是类似的。

     ESBook ESBook = new ESBook("3", "宝石 程序设计", "俄语", "宝石",
                88.88F, "我曾踏足山巅,也曾跌入低谷");
        bookByESRepstitory.save(ESBook);

//由于上面的id = 3 已经存在,故再次save 就是修改

4.3、删除

@Test
public void test2(){
    bookByESRepstitory.deleteById("1");
    bookByESRepstitory.deleteAll();
}

4.4、基本查询

1、ElasticsearchRepository提供了一些基本的查询方法:

@Test
public void testQuery(){
     Optional<BookByES> optionalById = this.bookByESRepstitory.findById("1");
     System.out.println(optionalById.get());
}

 @Test
    public void testFind(){
        // 查询全部,并按照价格降序排序
        //写法一: 
        Iterable<BookByES> items = this.bookByESRepstitory.findAll(Sort.by(Sort.Direction.DESC,
                "price"));
        //写法二: 
        Iterable<BookByES> items1 = this.bookByESRepstitory.findAll(Sort.by(Sort.Order.desc("price")));
    }

2、分页查询

Spring Data 自带的分页方案:

    @Test
    public void testByPage(){
        Sort sort = Sort.by(Sort.Direction.DESC,"id");
        //分页
        PageRequest pageRequest = PageRequest.of(0, 2, sort);
        Page<BookByES> all = bookByESRepstitory.findAll(pageRequest);
        for (BookByES bookByES : all) {
            System.out.println(bookByES);
        }
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7SZLIEI-1681375145183)(C:\Users\lps\AppData\Roaming\Typora\typora-user-images\image-20230413121434941.png)]

4.5、自定义方法查询

Spring Data 的另一个强大功能,是根据方法名称自动实现功能。

比如:你的方法名叫做:findByTitle,那么它就知道你是根据title查询,然后自动帮你完成,无需写实现类。

当然,方法名称要符合一定的约定

KeywordSampleElasticsearch Query String
AndfindByNameAndPrice{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
OrfindByNameOrPrice{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
IsfindByName{"bool" : {"must" : {"field" : {"name" : "?"}}}}
NotfindByNameNot{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
BetweenfindByPriceBetween{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqualfindByPriceLessThan{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
GreaterThanEqualfindByPriceGreaterThan{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
BeforefindByPriceBefore{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
AfterfindByPriceAfter{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
LikefindByNameLike{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWithfindByNameStartingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWithfindByNameEndingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/ContainingfindByNameContaining{"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}
InfindByNameIn(Collection<String>names){"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotInfindByNameNotIn(Collection<String>names){"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
NearfindByStoreNearNot Supported Yet !
TruefindByAvailableTrue{"bool" : {"must" : {"field" : {"available" : true}}}}
FalsefindByAvailableFalse{"bool" : {"must" : {"field" : {"available" : false}}}}
OrderByfindByAvailableTrueOrderByNameDesc{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

如:

import com.springsecurity.domain.ESBook;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author 阿水
 * @create 2023-04-13 11:05
 */
@Repository
//看实体类Id索引是什么类型 我这里是String
public interface ESBookRepstitory extends ElasticsearchRepository<ESBook, String> {
    /**
     * 根据描述查询书籍,带分页的
     * @param description
     * @return
     */
    List<ESBook> findESBookByDescription(String description, Pageable variable);
    /**
     * 根据作者和描述和标题查
     */
    List<ESBook> queryESBookByAuthorAndDescriptionOrTitle(String author,String description,String title);
    /**
     * 根据书的价格范围查询
     */
    List<ESBook> queryESBookByPriceBetween(Float price1,Float price2);
}
@Test
void esQueryCondition() {
    Sort sort = Sort.by(Sort.Order.desc("id"));
    PageRequest pageRequest = PageRequest.of(0, 2, sort);
    List<ESBook> EBooks = bookByESRepstitory.findESBookByDescription("我",pageRequest);
    for (ESBook bookByE : EBooks) {
        System.out.println(bookByE);
    }
}
@Test
void esQueryCondition2() {
    List<ESBook> esBooks = bookByESRepstitory.queryESBookByAuthorAndDescriptionOrTitle("盖伦", "哈嗨", "程序");
    for (ESBook book : esBooks) {
        System.out.println(book);
    }
}

@Test
void esQueryCondition3() {
    List<ESBook> esBooks = bookByESRepstitory.queryESBookByPriceBetween(18.88F,77.88F);
    for (ESBook book : esBooks) {
        System.out.println(book);
    }
}

4.6、使用NativeSearchQuery

@Autowired
private ElasticsearchRestTemplate restTemplate;
QueryBuilders.queryStringQuery() #指定字符串作为关键词查询,关键词支持分词
QueryBuilders.queryStringQuery("华为手机").defaultField("description");
//不指定feild,查询范围为所有feild
QueryBuilders.queryStringQuery("华为手机");
//指定多个feild
QueryBuilders.queryStringQuery("华为手机").field("title").field("description");

QueryBuilders.boolQuery          #子方法must可多条件联查
QueryBuilders.termQuery          #精确查询指定字段不支持分词
QueryBuilders.termQuery("description", "华为手机")
QueryBuilders.matchQuery         #按分词器进行模糊查询支持分词
QueryBuilders.matchQuery("description", "华为手机")    
QueryBuilders.rangeQuery         #按指定字段进行区间范围查询

- `QueryBuilders.boolQuery()`
- `QueryBuilders.boolQuery().must()`:相当于 and
- `QueryBuilders.boolQuery().should()`:相当于 or
- `QueryBuilders.boolQuery().mustNot()`:相当于 not 
- ——————————————————————————————————————————————————————————————————————————————————————————————————————

  @Test
    void naticeQuery() {
        NativeSearchQuery nativeSearchQuery =
                new NativeSearchQueryBuilder()
                        //.withQuery(QueryBuilders.queryStringQuery("山巅哈哈").defaultField("description"))
                        //多条件查询
                        .withQuery(QueryBuilders.boolQuery()
                                .must(QueryBuilders.queryStringQuery("山巅哈哈").defaultField("description"))
                                .should(QueryBuilders.queryStringQuery("宝石").defaultField("title"))
                        )
                        .withPageable(PageRequest.of(0, 2))
                        .build();
        SearchHits<ESBook> search = restTemplate.search(nativeSearchQuery, ESBook.class);
        List<SearchHit<ESBook>> searchHits = search.toList();
        for (SearchHit<ESBook> searchHit : searchHits) {
            System.out.println(searchHit);
        }

    }

举个例子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbyhHOcz-1681375145184)(C:\Users\lps\AppData\Roaming\Typora\typora-user-images\image-20230413160753038.png)]

5、es场景

场景一:对外暴露的数据(数据量大的)的用es,如果不需要对外暴露,不需要全文检索的话,那么直接从数据查,所以做项目分析数据分成2块(哪些数据需要放es,从es查,哪些不需要)

场景二:作为mysql的外置索引,把作为数据库查询条件的列数据放到es里面,这样在查询的时候,先从es查询出符合条件的id,然后根据id去数据库查,数据维护大,一旦es宕机,就麻烦了

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

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

相关文章

【是C++,不是C艹】 第一个C++程序 | 命名空间 | 输入输出

&#x1f49e;&#x1f49e; 欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e; &#x1f449;专栏&#xff1a;《是C&#xff0c;不是C艹》&#x1f448; 前言&#xff1a; 在认识了C的来历之后&#xff0c;我们就要开始正式学习C了&#xff0c;系好安全带&#xff0c;准备…

阿里云安全ACP认证考试实验之云盾之云安全中心与态势感知入门体验

“更多玩转云产品” 1、实验概述 通过本实验可对云安全中心&#xff0c;态势感知的一些基本操作有深入了解以及如何来对实例进行安全监控 2、实验目标 完成此实验可以掌握的能力有&#xff1a; 在安骑士中添加白名单、登录安全设置 通过态势感知查看实例的相关告警威胁 3…

数值区间的模糊匹配,二分查找的应用

先看图: 需求很明确,要根据左边的值,显示右边的值。 比如,现在拿到的值是 17.12,那么应该显示成 15;拿到 17.599 ,那么应该显示成 20. 先找规律: 为了便于说明,暂且将左边的值设为 x, 右边的值设为 y. 第一行和最后一行可以写死成 0 与 1500;余下的每行,x 的区间是…

Vue CLI 创建一个项目

vue create 运行以下命令来创建一个新项目&#xff1a; vue create hello-world警告 如果你在 Windows 上通过 minTTY 使用 Git Bash&#xff0c;交互提示符并不工作。你必须通过 winpty vue.cmd create hello-world 启动这个命令。不过&#xff0c;如果你仍想使用 vue crea…

发布会前准备新闻通稿的重要性,为什么媒体不会原稿发布报道?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体 胡老师。 最近有宣传的小伙伴问胡老师&#xff0c;为什么我们精心准备的新闻通稿&#xff0c;媒体没有按照稿子发布呢&#xff1f;今天就与大家交流下这方面的经验。 一&#xff0c;发布会前准备新…

中断嵌套实验

使用汇编语言&#xff0c;要求&#xff1a; 外部中断1可以嵌套外部中断0 没有中断时&#xff0c;8个LED发光二极管以0.1s的速度闪烁。 有外部中断0时&#xff0c;8个LED发光二极管以0.1s的速度流水点亮。&#xff08;中断子程序0&#xff09; 有外部中断1时&#xff0c;会打断外…

还在为招生发愁?一文get中外合办院校招生技巧

生源&#xff0c;是任何一所高校的生存之本和生命线。因此&#xff0c;正确的招生策略&#xff0c;对于院校来说显得格外重要。 近几年&#xff0c;越来越多的家长和学生开始关注中外合办大学&#xff0c;随之而来的中外合办大学的生源竞争也越来越激烈。那么&#xff0c;有哪…

学好虚拟化,首先要学Linux

上次讲到了虚拟化的基础知识&#xff0c;比如虚拟化的应用、各个厂商都是通过何种技术路径来实现的等等&#xff0c;本篇想记录一下我学习到的CPU内存虚拟化和网络虚拟化相关知识&#xff0c;通过记录来制造反馈&#xff0c;让自己更有效地学习。需要注意的是&#xff0c;学习虚…

这 7个 AI 写作助手,太实用了

想象一下&#xff1a;你正在办公桌前为你的广告输入标题&#xff0c;但你突然思维阻塞并卡住了&#xff0c;可惜这时还没有神奇的软件可以帮助你想出点子。或许是有的&#xff1f; 2023 年&#xff0c;AI 写作工具似乎不可避免地会很快融入我们的工作流程中。现代知识工作者已…

政府大数据中心数据资源平台建设方案WORD2022

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除 1.1 项目建设内容 对于本次区级大数据资源平台的建设&#xff0c;将按照“总体规划一步到位&#xff0c;平台建设分步实施&#xff0c;数据赋能逐步升级”的原则&#xff0c;落…

理解什么是DTO?什么是AutoMapper?

什么是DTO? .Net DTO是一个对象&#xff0c;它定义了数据如何在网络上发送。它只用于发送和接收数据&#xff0c;不包含任何业务逻辑。使用DTO的原因有以下几个&#xff1a; 将服务层与数据库层分离隐藏客户端不需要查看的特定属性省略一些属性以减少有效负载大小处理嵌套对象…

【LeetCode: 233. 数字 1 的个数 | 暴力递归=>记忆化搜索=>动态规划 | 数位dp】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Term Suggester 中 suggest_mode 的三种模式missing、popular、always 的区别

1、Term Suggester term suggester 正如其名&#xff0c;只基于 tokenizer 之后的单个 term 去匹配建议词&#xff0c;并不会考虑多个term之间的关系 POST <index>/_search { "suggest": {"<suggest_name>": {"text": "<s…

VM——VMware装Centos

一、创建虚拟机配置 打开VMware&#xff0c;创建新虚拟机 选择自定义&#xff0c;下一步 选择16.x&#xff0c;然后下一步 选择稍后安装&#xff0c;然后下一步 选择Linux、镜像版本&#xff0c;然后下一步 输入虚拟机名称&#xff0c;选择存放位置&#xff0c;然后下一步 选择…

串口UART介绍

【记录所学】 1. 串口的硬件介绍 UART的全称是Universal Asynchronous Receiver and Transmitter&#xff0c;即异步发送和接收。串口在嵌入式中用途非常的广泛&#xff0c;主要的用途有&#xff1a; 打印调试信息&#xff1b;外接各种模块&#xff1a;GPS、蓝牙&#xff1b…

【java web篇】MyBatis实现增删改查

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

Git使用教程:从入门到精通(以Gitee为例)

一、前言 Git是一款分布式版本控制系统&#xff0c;可以帮助开发者更好地管理代码。在众多的Git平台中&#xff0c;Gitee是国内最受欢迎的Git平台之一。本篇文章将介绍如何使用Git进行代码管理&#xff0c;并以Gitee为例&#xff0c;详细讲解Git的基本操作和常用命令。 二、深入…

JS学习笔记(一)

从编程模式看&#xff1a;JS是结构化、事件驱动的动态语言&#xff0c;支持声明式和指令式两种模式&#xff0c;所以JS是一个多模式的语言。面向对象和函数式是常用的两种模式。 函数式编程 基本概念&#xff1a;函数是什么&#xff1f;函数是数据集到目标的一种关系。在函数式…

Windows逆向安全(一)之基础知识(十)

汇编一维数组 之前的文章学习过了四种基本类型&#xff1a;char short int long的汇编表示形式 因为它们的数据宽度都小于等于32位&#xff0c;所以都可以只用一个通用寄存器来存储 接下来的数组显然就无法只用一个通用寄存器就可以存储了 在学习数组之前&#xff0c;再学习…

云可见性和端口欺骗:已知的未知

与所有技术一样&#xff0c;新工具是建立在以前的基础上的迭代&#xff0c;经典的网络日志记录和指标也不例外。 网络流量的工具、检测和监控在私有云和内部部署中几乎没有变化。今天使用的许多日志和指标已有将近二十年的历史&#xff0c;最初是为了解决计费等问题而设计的。…