更多有关博主写的往期Elasticsearch文章
| 标题 | 地址 | 
|---|---|
| 【ElasticSearch 集群】Linux安装ElasticSearch集群(图文解说详细版) | https://masiyi.blog.csdn.net/article/details/131109454 | 
| 基于SpringBoot+ElasticSearch 的Java底层框架的实现 | https://masiyi.blog.csdn.net/article/details/121534307 | 
| ElasticSearch对标Mysql,谁能拔得头筹? | https://masiyi.blog.csdn.net/article/details/122661822 | 
| 同事说关键字查询用Mysql,我上去就是一个高压锅,用ElasticSearch不香吗? | https://masiyi.blog.csdn.net/article/details/122701654 | 
| 新年第一天,老板让升级ElasticSearch版本,我说得加钱 | https://masiyi.blog.csdn.net/article/details/122819455 | 
| 使用了ElasticSearch之后,公司系统查询速度快了50倍,工资直接翻一倍 | https://masiyi.blog.csdn.net/article/details/122819455 | 
| ElasticSearch实战教程PostMan版(超级详细版) | https://masiyi.blog.csdn.net/article/details/123048119 | 
| Linux安装ElasticSearch以及Ik分词器(图文解说详细版) | https://masiyi.blog.csdn.net/article/details/121509681 | 
文章目录
- 🐝第一步,创建一个springboot项目
 - 🐝第二步,导入spring-boot-starter-data-elasticsearch依赖
 - 🐝第三步,配置yml文件
 - 🐝第四步,编写es索引对应的实体类
 - 🐝第五步,编写实体类对应的mapper
 - 🐝第六步,使用框架自带的增删改查
 - 🐝增
 - 🐝使用ElasticsearchRestTemplate
 - 🐝使用mapper
 - 🐝设置指定的id
 - 🐝批量保存
 
- 🐝删
 - 🐝传入实体类删
 - 🐝传入id删
 - 🐝删除索引里面所有的数据(慎用)
 
- 🐝改
 - 🐝实体改
 - 🐝实体改全部
 - 🐝先查再update
 - 🐝直接使用局部更新
 
- 🐝查
 - 🐝根据id查
 - 🐝根据id列表查
 - 🐝查询全部数据
 - 🐝排序查-正序
 - 🐝排序查-倒序
 - 🐝分页查
 - 🐝自定义复杂的查询
 
- 🐝第七步,使用JPA风格的查询方式
 - 🐝根据age查询
 - 🐝查询所有符合age的数据
 - 🐝查询最top的数据
 
导语
发现很多公司都是自己导入原生的jar包自己去封装一套Elasticsearch的框架,这样虽然可以自定义业务,但是需要花费很多的时间,其实spring官方有一套springboot的starter,帮助大家快速入手官网的starter,这篇博客也会介绍使用该starter连接Elasticsearch的集群。该starter有点像mybatisplus+Jpa,如果熟悉这两个框架的同学应该很快就会上手。
官网地址:
 https://docs.spring.io/spring-data/elasticsearch/docs/4.0.x/reference/html/#preface
本文所有的代码都已经提交到git仓库中,仓库地址:
 https://gitee.com/WangFuGui-Ma/spring-boot-elasticSearch
现在我们开始按照步骤进行spring-boot-starter-data-elasticsearch的使用,本文中使用的spring boot版本为2.7.x 对于的elasticsearch客户端版本为7.17.x
🐝第一步,创建一个springboot项目
🐝第二步,导入spring-boot-starter-data-elasticsearch依赖
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
		</dependency>
 
其他依赖
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--json-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.76</version>
		</dependency>
		<!--json-->
 
🐝第三步,配置yml文件
spring:
  elasticsearch:
    uris:
      - 192.168.75.128:9200
      - 192.168.75.129:9200
      - 192.168.75.130:9200
server:
  port: 8889
 
uris这里填的是集群的地址,如果你的es是单机版的,直接填一个就行了
🐝第四步,编写es索引对应的实体类
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.WriteTypeHint;
/**
 * @Author masiyi
 * @Date 2023/6/14 13:46
 * @PackageName:com.masiyi.springbootstarterdataelasticsearch.doman
 * @ClassName: ElasticTest
 * @Description: TODO
 * @Version 1.0
 */
@Data
@Document(indexName = "elastic_test",writeTypeHint = WriteTypeHint.FALSE)
public class ElasticTest {
    private Long id;
    private String name;
    private Integer age;
    private Boolean isMan;
}
 
注:
- id这个类型一定要写,否则会报错
 - indexName对应es中的索引
 - writeTypeHint如果为false则不会自动创建索引
 
🐝第五步,编写实体类对应的mapper
类似mybatis一样,我们需要创建对应的mapper
public interface ElasticTestMapper extends ElasticsearchRepository<ElasticTest,Long> {
}
 
继承ElasticsearchRepository类,第一个泛型添es对应的实体类,第二个泛型添id的类型
🐝第六步,使用框架自带的增删改查
我们这次用单元测试的方法跟大家演示框架的用法
注入刚刚创建的mapper和框架的ElasticsearchRestTemplate
🐝增
🐝使用ElasticsearchRestTemplate
   @Test
    void save() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setName("李四");
        elasticTest.setAge(23);
        elasticTest.setIsMan(true);
        elasticsearchTemplate.save(elasticTest);
    }
 
🐝使用mapper
    @Test
    void insert() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setName("李四");
        elasticTest.setAge(23);
        elasticTest.setIsMan(true);
        elasticTestMapper.save(elasticTest);
    }
 
🐝设置指定的id
   @Test
    void insertId() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setName("掉头发的王富贵");
        elasticTest.setAge(25);
        elasticTest.setIsMan(true);
        elasticTest.setId(2434235L);
        elasticTestMapper.save(elasticTest);
    }
 
🐝批量保存
    @Test
    void saveAll() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setName("李四");
        elasticTest.setAge(24);
        elasticTest.setIsMan(true);
        elasticTestMapper.saveAll(Arrays.asList(elasticTest));
    }
 
🐝删
🐝传入实体类删
    @Test
    void delete() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setId(2342342L);
        elasticTestMapper.delete(elasticTest);
    }
 
🐝传入id删
    @Test
    void deleteById() {
        elasticTestMapper.deleteById(2342342L);
    }
 
🐝删除索引里面所有的数据(慎用)
    @Test
    void deleteAll() {
        elasticTestMapper.deleteAll();
    }
 
🐝改
🐝实体改
    @Test
    void update() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setName("掉头发的王富贵hh");
        elasticTest.setId(2434235L);
        elasticTestMapper.save(elasticTest);
    }
 
这里改会把其他的不在实体里面为null的数据清空
🐝实体改全部
 @Test
    void updateAll() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setName("掉头发的王富贵");
        elasticTest.setAge(24);
        elasticTest.setIsMan(true);
        elasticTest.setId(2434234L);
        elasticTestMapper.save(elasticTest);
    }
 
如果我们只需要局部更新,可以使用下面的两种方法
🐝先查再update
    @Test
    void updateNow() {
        ElasticTest elasticTest = elasticTestMapper.findById(2434234L).get();
        elasticTest.setName("不掉头发的王富贵");
        elasticTestMapper.save(elasticTest);
    }
 
但是这个方法会消耗性能,所以推荐用下面的方法
🐝直接使用局部更新
    @Test
    void updateNow2() {
        ElasticTest elasticTest = new ElasticTest();
        elasticTest.setName("掉头发的王富贵h");
        Map map = JSONObject.parseObject(JSONObject.toJSONString(elasticTest), Map.class);
        UpdateQuery updateQuery = UpdateQuery.builder("0ZUv7okBcQy9f7u_tXkH").withDocument(Document.from(map)).build();
        elasticsearchTemplate.update(updateQuery, IndexCoordinates.of("elastic_test"));
    }
 
🐝查
🐝根据id查
    @Test
    void select() {
        Optional<ElasticTest> byId = elasticTestMapper.findById(2434234L);
        byId.ifPresent(System.out::println);
    }
 
🐝根据id列表查
  @Test
    void findAllById() {
        Iterable<ElasticTest> allById = elasticTestMapper.findAllById(Arrays.asList(2434234L));
        allById.forEach(System.out::println);
    }
 
🐝查询全部数据
    @Test
    void findAll() {
        Iterable<ElasticTest> allById = elasticTestMapper.findAll();
        allById.forEach(System.out::println);
    }
 
🐝排序查-正序
    @Test
    void findAllSort() {
        Sort age = Sort.by("age").ascending();
        Iterable<ElasticTest> all = elasticTestMapper.findAll(age);
        all.forEach(System.out::println);
    }
 
🐝排序查-倒序
    @Test
    void findAllSortDE() {
        Sort age = Sort.by("age").descending();
        Iterable<ElasticTest> all = elasticTestMapper.findAll(age);
        all.forEach(System.out::println);
    }
 
🐝分页查
    @Test
    void findAllPage() {
        PageRequest pageRequest = PageRequest.of(0, 10);
        Page<ElasticTest> all = elasticTestMapper.findAll(pageRequest);
        all.forEach(System.out::println);
        System.out.println(JSON.toJSONString(all));
    }
 
🐝自定义复杂的查询
 @Test
    void findMyStyle() {
        TermQueryBuilder termQueryBuilder = new TermQueryBuilder("name.keyword", "掉头发的王富贵");
        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(termQueryBuilder);
        SearchHits<ElasticTest> search = elasticsearchTemplate.search(nativeSearchQuery, ElasticTest.class);
        List<SearchHit<ElasticTest>> hitList = search.getSearchHits();
        for (SearchHit<ElasticTest> hit : hitList) {
            ElasticTest entity = hit.getContent(); // 获取实体对象
            System.out.println(entity);
            String index = hit.getIndex(); // 获取索引名
            System.out.println(index);
        }
    }
 
🐝第七步,使用JPA风格的查询方式
如果会用jpa的同学看到这个可能会非常得熟悉

 可以自定义查询方法find...
🐝根据age查询
    ElasticTest findByAge(Integer age);
 
🐝查询所有符合age的数据
    List<ElasticTest> findAllByAge(Integer age);
 
🐝查询最top的数据
    ElasticTest findTopByAge(Integer age);
 
如果你使用的是idea这种高级的编辑器,你在mapper写方法的时候会自动提示你。
通过本文的学习,我们探索了在Spring Boot应用中使用Elasticsearch的方法以及如何连接到Elasticsearch集群。Elasticsearch作为一款强大的搜索和分析引擎,在现代应用开发中扮演着至关重要的角色。借助于Spring Boot和spring-boot-starter-data-elasticsearch,我们能够以更加便捷的方式将Elasticsearch集成到我们的项目中,实现高效的数据搜索与分析。
通过配置简单明了的属性,我们能够快速地将Spring Boot应用连接到Elasticsearch集群,实现数据的索引、搜索和分析。借助于Spring Data Elasticsearch提供的强大功能,我们能够轻松地定义实体类、进行CRUD操作,并且利用Elasticsearch的全文搜索和分词等特性,让我们的应用具备更高效的查询和检索能力。


























