ElasticSearch集成SpringBoot

Posted 唐宋xy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch集成SpringBoot相关的知识,希望对你有一定的参考价值。

上一篇介绍了JavaAPI来操作ES,虽然易用,但是如果操作大量的数据并且程序相对复杂,那么会有大量冗余的代码和API操作,SpringBoot作为轻量级易用框架自然也帮我们封装好了各种API操作,只需要操作数据库一样操作ES即可,一起看看吧

代码已上传Github: https://github.com/chenliang15405/common-study/tree/main/es-spring

Maven依赖

  • pom.xml中增加依赖

    <!--  elasticsearch 依赖      -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    

    添加elasticsearchstarter依赖即可,减少很多配置代码,springboot已经内置了很多配置

  • properties配置

    配置文件中只需要增加elasticsearch的连接配置即可

    # es服务地址
    elasticsearch.host=127.0.0.1
    # es服务端口
    elasticsearch.port=9200
    

ElasticSearch配置

前置配置
  • 增加ElasticSearch与Spring配置

    将需要使用的RestHighLevelClient客户端Bean,注入到Spring中,由Spring管理

    // 这里指定的就是配置文件中配置的名称的前缀,将配置文件中的配置自动注入到bean中
    @ConfigurationProperties(prefix = "elasticsearch")
    @Configuration
    @Data  // 注意这里使用了lombok,如果去掉该注解,需要给host和port增加getter/setter
    public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {
    
        private String host;
        private Integer port;
    
        /**
         * 返回ESClient对象
         */
        @Override
        public RestHighLevelClient elasticsearchClient() {
            RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
            RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
            return restHighLevelClient;
        }
    
    }
    
  • 增加Repository

    与操作Database一样,需要增加接口,并且继承``ElasticsearchRepository类,那么Spring`在启动的时候就会自动扫描该类,通过动态代理相应的实现类,可以直接使用内置的相关方法,高效!

    @Repository
    public interface ProductDao extends ElasticsearchRepository<Product, Long> {
    }
    

    使用方式与Spring提供的方式基本一致,无论是Database还是Es或者MongoDB,基本都是一致的方式

索引操作

  • 配置索引Bean

    通过注解可以直接将Bean中的字段和ES中的索引字段进行映射,后续直接操作Bean就可以操作ES中的索引,非常的方便。

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Document(indexName = "product", shards = 3, replicas = 1) // 索引名称, 主分片数量 -> 就是将数据分配到多个分片中,不保存在一个分片(节点), replicas:副本的数量,每个主分片都会创建这么多的副本数量
    public class Product {
    
        //必须有id,这里的id是全局唯一的标识,等同于es中的"_id"
        @Id
        private Long id;
        /**
         * type: 字段数据类型
         * analyzer: 分词器类型
         * index: 是否索引
         * keyword: 短语,不进行分词
         */
        @Field(type = FieldType.Text, analyzer = "ik_max_word")
        private String title;
        @Field(type = FieldType.Keyword)
        private String category;
        @Field(type = FieldType.Double)
        private Double price;
        @Field(type = FieldType.Keyword, index = false)
        private String images;
    }
    
    • @Document
      • 文档注解,表示当前的类需要映射为一个文档,并且在注解中还可以指定索引的名称—indexNameshards表示当前的索引需要有多少个分片,replicas表示当前的分片需要有多少个副本(相当于从分片备份),注意这里设置的是1,表示每个分片都需要一个副本,所以一共就有3个副本。
    • @Id
      • 主键id注解,表示当前字段是文档的主键,必须要有id注解,等同于ES中的_id
    • @Field
      • 字段注解,表示当前的字段映射为当前文档中的一个字段,并且通过type指定当前字段的类型,并且还可以通过analyzer指定当前使用的分词器,index表示当前字段是否需要索引,如果不进行索引,那么无法通过该字段进行搜索
  • 索引的基本操作

    可以通过Springboot-elasticsearch-starter中提供的ElasticsearchRestTemplate模版类,可以直接操作ES,

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringDataESIndexTest {
    
        @Autowired
        private ElasticsearchRestTemplate elasticsearchRestTemplate;
    
        @Test
        public void createIndex() {
            // 创建索引,spring容器启动就会创建索引,因为Product已经配置索引注解映射
            System.out.println("自动创建索引");
        }
    
        @Test
        public void deleteIndex() {
            boolean deleteIndex = elasticsearchRestTemplate.deleteIndex(Product.class);
            System.out.println("删除索引result:  " + deleteIndex);
        }
    }
    

文档操作

  • 基本简单操作

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringDataESProductDaoTest {
    
        @Autowired
        private ProductDao productDao;
    
        /**
         * 新增
         */
        @Test
        public void save(){
            Product product = new Product();
            product.setId(2L);
            product.setTitle("华为手机");
            product.setCategory("手机");
            product.setPrice(2999.0);
            product.setImages("http://www.atguigu/hw.jpg");
            productDao.save(product);
        }
    
        //修改
        @Test
        public void update(){
            Product product = new Product();
            product.setId(1L);
            product.setTitle("小米2手机");
            product.setCategory("手机");
            product.setPrice(9999.0);
            product.setImages("http://www.atguigu/xm.jpg");
            productDao.save(product);
        }
    
        //根据id查询
        @Test
        public void findById(){
            Product product = productDao.findById(1L).get();
            System.out.println(product);
        }
    
        //查询所有
        @Test
        public void findAll(){
            Iterable<Product> products = productDao.findAll();
            for (Product product : products) {
                System.out.println(product);
            }
        }
    
        //删除
        @Test
        public void delete(){
            Product product = new Product();
            product.setId(1L);
            productDao.delete(product);
        }
    
        //批量新增
        @Test
        public void saveAll(){
            List<Product> productList = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                Product product = new Product();
                product.setId(Long.valueOf(i));
                product.setTitle("["+i+"]小米手机");
                product.setCategory("手机");
                product.setPrice(1999.0+i);
                product.setImages("http://www.atguigu/xm.jpg");
                productList.add(product);
            }
            productDao.saveAll(productList);
        }
    
        //分页查询
        @Test
        public void findByPageable(){
            //设置排序(排序方式,正序还是倒序,排序的id)
            Sort sort = Sort.by(Sort.Direction.DESC,"id");
            int currentPage=0;//当前页,第一页从0开始,1表示第二页
            int pageSize = 5;//每页显示多少条
            //设置查询分页
            PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
            //分页查询
            Page<Product> productPage = productDao.findAll(pageRequest);
            for (Product Product : productPage.getContent()) {
                System.out.println(Product);
            }
        }
    
    }
    
  • term查询

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringDataESSearchTest {
    
        @Autowired
        private ProductDao productDao;
    
        /**
         * term查询(不分词查询,只有完全匹配到,或者指定的字段中 包含 term查询的 值才可以,相当于 like, 而普通的查询时将值分词之后进行匹配查询的)
         * search(termQueryBuilder) 调用搜索方法,参数查询构建器对象
         */
        @Test
        public void termQuery(){
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "手机");
            Iterable<Product> products = productDao.search(termQueryBuilder);
            for (Product product : products) {
                System.out.println(product);
            }
        }
    
        /**
         * term查询加分页
         */
        @Test
        public void termQueryByPage(){
            int currentPage= 0 ;
            int pageSize = 5;
            //设置查询分页
            PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米");
            Iterable<Product> products = productDao.search(termQueryBuilder,pageRequest);
            for (Product product : products) {
                System.out.println(product);
            }
        }
    
    }
    

ElasticSearchSpringboot集成还是非常方便的,因为Springboot已将将相关的配置在其内部配置好了,只需要增加少量的配置就可以使用了!并且使用方式较数据库保持了一致的使用方式,便于使用。

在这里插入图片描述

微信公众号「指尖上的代码」,欢迎关注~

原创不易, 点个赞再走呗~ 欢迎关注,给你带来更精彩的文章!

你的点赞和关注是写文章最大的动力~

以上是关于ElasticSearch集成SpringBoot的主要内容,如果未能解决你的问题,请参考以下文章

精通系列SpringBoot集成ElasticSearch+项目实战

精通系列SpringBoot集成ElasticSearch+项目实战

精通系列SpringBoot集成ElasticSearch+项目实战

springboot集成ElasticSearch

springboot集成elk 三:springboot + Elasticsearch Rest-Client

springboot集成elasticsearch全文搜索高亮显示实践