SpringBoot整合Elasticsearch

一、SpringDataES实现ES操作

1、项目搭建

  1. 在myes空项目下,创建一个新模块,创建springboot项目myes2
    在这里插入图片描述

  2. 选择2.7.9版本,并且选择两个依赖
    在这里插入图片描述

  3. 创建application.yml文件,配置ES

    spring:
      elasticsearch:
        uris: 192.168.126.24:9200
    
  4. 创建包com.zzx.myes2.document,在包下创建实体类Product

    package com.zzx.myes2.document;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    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;
    
    @Document(indexName = "product",createIndex = true)
    @Data
    @AllArgsConstructor
    public class Product {
        @Id
        @Field(type = FieldType.Integer,store = true,index = true)
        private Integer id;
        @Field(type = FieldType.Text,store = true,index = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
        private String productName;
        @Field(type = FieldType.Text,store = true,index = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
        private String productDesc;
    
    }
    
    

    1)@Document:标记在类上,标记实体类为文档对象,一般有如下属性:
    indexName:对应索引的名称
    createIndex:是否自动创建索引
    2)@Id:标记在成员变量上,标记一个字段为主键,该字段的值会同步到ES该文档的id值。
    3)@Field:标记在成员变量上,标记为文档中的域,一般有如下属性:
    type:域的类型
    index:是否创建索引,默认是 true。即可以通过该域的关键词进行搜索
    store:是否单独存储,默认是 false。即相当于将该列进行单独存储
    analyzer:分词器
    searchAnalyzer:搜索时的分词器。一般与analyzer属性保持一致即可。

2、使用Repository接口方法

  1. 创建包com.zzx.myes2.repository,在包下创建ProductRepository接口

    package com.zzx.myes2.repository;
    
    import com.zzx.myes2.document.Product;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    
    public interface ProductRepository extends ElasticsearchRepository<Product,Integer> {
    }
    
  2. 在test根目录下,创建包com.zzx.myes2.repositorytest,在包下创建ProductRepositoryTest测试类

    package com.zzx.myes2.repositorytest;
    
    import com.zzx.myes2.document.Product;
    import com.zzx.myes2.repository.ProductRepository;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.util.Optional;
    
    @SpringBootTest
    public class ProductRepositoryTest {
        @Autowired
        private ProductRepository repository;
    	//新建文档
        @Test
        public void addDocument(){
            Product product = new Product(1, "小米手机", "暖手宝");
            repository.save(product);
        }
        //更新文档
        @Test
        public void updateDocument(){
            Product product = new Product(1, "小米手机2", "暖手宝2");
            repository.save(product);
        }
        //查询所有文档
        @Test
        public void findAllDocument(){
            Iterable<Product> all = repository.findAll();
            for (Product product : all) {
                System.out.println(product);
            }
        }
        //根据id查询文档
        @Test
        public void findDocumentById(){
            Optional<Product> product = repository.findById(1);
            System.out.println(product.get());
        }
        //根据id删除文档
        @Test
        public void deleteDocument(){
            repository.deleteById(1);
        }
    
    }
    
    

    此时操作时可能会报错,可能是springboot版本跟Elasticsearch版本不一致导致的响应正文无法解析,但是这个操作是正确的,能存到ES服务器中。

3、使用DSL查询文档

使用@Query注解实现DSL查询文档

  1. 往addDocument方法中加入添加文档的语句

    repository.save(new Product(2, "小米手机3", "暖手宝3"));
    repository.save(new Product(3, "小米手机4", "暖手宝4"));
    repository.save(new Product(4, "小米手机5", "暖手宝5"));
    repository.save(new Product(5, "小米手机6", "暖手宝6"));
    

    不过因为无法解析响应正文,每次只能添加一条。

  2. 在ProductRepository接口下添加两个方法

    @Query("{"+
            " \"match\" :{"+
            " \"productDesc\": \"?0\""+
            "}"+
    "}")
    List<Product> findByProductDescMatch(String keyword);
    @Query("{\n" +
            "    \"match\": {\n" +
            "      \"productDesc\": {\n" +
            "        \"query\": \"?0\",\n" +
            "        \"fuzziness\": 1\n" +
            "      }\n" +
            "    }\n" +
            "  }")
    List<Product> findByProductDescFuzzy(String keyword);	
    
  3. 在com.zzx.myes2.repositorytest包下的ProductRepositoryTest类中添加两个方法

    @Test
    public void testFindByProductDescMatch(){
        List<Product> list = repository.findByProductDescMatch("我想能暖手的手机");
        list.forEach(System.out::println);
    }
    @Test
    public void testFindByProductDescFuzzy(){
        List<Product> list = repository.findByProductDescFuzzy("冷手宝");
        list.forEach(System.out::println);
    }
    

    两个方法都根据ProductDesc搜索,但是第一个方法是普通搜索,第二个则是模糊查询,可以容错。

4、按照规则来命名方法进行查询

按照规则来命名方法,方法名以findBy开头

  1. 在com.zzx.myes2.repository包下的ProductRepository接口中添加方法

    List<Product> findByProductName(String productName);
    List<Product> findByProductNameOrProductDesc(String productName,String productDesc);
    List<Product> findByIdBetween(Integer startId,Integer endId);
    
  2. 在Test根目录下的com.zzx.myes2.repositorytest包下的ProductRepositoryTest类中添加方法进行测试

     @Test
    public void testFindByProductName(){
        List<Product> list = repository.findByProductName("小米手机3");
        list.forEach(System.out::println);
    }
    @Test
    public void testFindByProductNameOrProductDesc(){
        List<Product> list = repository.findByProductNameOrProductDesc("小米手机3","暖手宝x");
        list.forEach(System.out::println);
    }
    @Test
    public void testFindByIdBetween(){
        List<Product> list = repository.findByIdBetween(1,2);
        list.forEach(System.out::println);
    }
    

    在继承ElasticsearchRepository接口的接口下,编写方法,以findBy开头,并且以一定的规则命名即可通过该方法进行查询。此时不用编写DSL语句

5、分页查询

  1. 在com.zzx.myes2.repository包下的ProductRepository接口中添加方法

    Page<Product> findByProductDesc(String productDesc, Pageable pageable);
    
  2. 在Test根目录下的com.zzx.myes2.repositorytest包下的ProductRepositoryTest类中添加方法进行测试

    //使用自定义的分页查询
    @Test
    public void testFindPage2(){
        //根据id倒序排序
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        //显示第一页,每页显示一条
        Pageable pageable = PageRequest.of(0, 1,sort);
        Page<Product> page = repository.findByProductDesc("暖手",pageable);
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("总条数:"+page.getTotalElements());
        System.out.println("数据:"+page.getContent());
    }
    //此时使用继承的固定方法实现分页查询
    @Test
    public void testFindPage(){
        //显示第一页,每页显示一条
        Pageable pageable = PageRequest.of(0, 1);
        Page<Product> page = repository.findAll(pageable);
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("总条数:"+page.getTotalElements());
        System.out.println("数据:"+page.getContent());
    }
    
    

    第二个方法直接调用即可。

6、结果排序

  1. 在Test根目录下的com.zzx.myes2.repositorytest包下的ProductRepositoryTest类中添加方法进行测试
    @Test
    public void testFindSort(){
        //根据id倒序排序
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        Iterable<Product> products = repository.findAll(sort);
        for (Product product : products) {
            System.out.println(product);
        }
    }
    

二、SpringDataES的template工具类实现ES操作

1、操作索引

  1. 创建包com.zzx.myes2.templatetest,在包下创建TemplateTest类

    package com.zzx.myes2.templatetest;
    
    import com.zzx.myes2.document.Product;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
    import org.springframework.data.elasticsearch.core.IndexOperations;
    
    @SpringBootTest
    public class TemplateTest {
        @Autowired
        private ElasticsearchRestTemplate template;
    
        //新增索引
        @Test
        public void addIndex(){
            //获得索引操作对象
            IndexOperations indexOperations = template.indexOps(Product.class);
            //创建索引 修改Product实体类,自动创建设置为false并且修改索引名字
            indexOperations.create();
        }
        //删除索引
        @Test
        public void deleteIndex(){
            //获得索引操作对象
            IndexOperations indexOperations = template.indexOps(Product.class);
            //删除索引
            indexOperations.delete();
        }
    
    }
    
    

    即通过注入SpringDataES的ElasticsearchRestTemplate工具类,调用该类的方法操作ES。

2、增删改查文档

  1. 在com.zzx.myes2.templatetest包下的TemplateTest类添加增加文档方法

    //新增/修改文档
    @Test
    public void addDocument(){
        //获得索引操作对象
        Product hzw = new Product(7, "hzw", "海贼,王路飞");
        template.save(hzw);
    }
    //删除文档
    @Test
    public void delDocument(){
        template.delete("7",Product.class);
    }
    

    此时添加和删除操作会返回无法解析响应正文的错误,但是文档可以操作成功。

  2. 在com.zzx.myes2.templatetest包下的TemplateTest类添加查询文档方法

    //查询文档
    @Test
    public void searchDocument(){
        //1.确定查询方式
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        //2.构建查询条件
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQueryBuilder).build();
        //3.查询
        SearchHits<Product> search = template.search(query, Product.class);
        //4.处理查询结果
        for (SearchHit<Product> productSearchHit : search) {
            System.out.println(productSearchHit);
        }
    }
    

3、复杂查询

  1. 在com.zzx.myes2.templatetest包下的TemplateTest类添加复杂查询文档方法

    //复杂查询文档
    @Test
    public void searchDocument2(){
        String productName = "hzw";
        String productDesc="暖手宝3";
        //1.确定查询方式 多条件查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //如果没有传入参数 查询所有
        if((productName==null||productName.length()==0)&&(productName==null||productName.length()==0)) {
            MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
            boolQueryBuilder.must(matchAllQueryBuilder);
        }else{
            if(productName != null && productName.length()>0){
                MatchQueryBuilder productName1 = QueryBuilders.matchQuery("productName", productName);
                boolQueryBuilder.should(productName1);
            }
            if(productDesc!= null && productDesc.length()>0){
                MatchQueryBuilder productDesc1 = QueryBuilders.matchQuery("productDesc", productDesc);
                boolQueryBuilder.should(productDesc1);
            }
        }
        //2.构建查询条件
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).build();
        //3.查询
        SearchHits<Product> search = template.search(query, Product.class);
        //4.处理查询结果
        for (SearchHit<Product> productSearchHit : search) {
            System.out.println(productSearchHit);
        }
    }
    

    复杂文档查询和文档查询的步骤除了前面查询方式不同之外基本一致,创建多条件查询构造器BoolQueryBuilder,通过往该构造器中添加查询条件即可,添加的方式有must、should、mustNot三种。

4、分页查询

  1. 在com.zzx.myes2.templatetest包下的TemplateTest类添加分页查询文档方法

    // 分页查询文档
    @Test
    public void searchDocumentPage(){
        //1.确定查询方式
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        //2.构建查询条件
        //分页条件
        PageRequest pageable = PageRequest.of(0, 1);
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQueryBuilder).withPageable(pageable).build();
        //3.查询
        SearchHits<Product> search = template.search(query, Product.class);
        //4.将查询结果封装为page对象
        List<Product> products = new ArrayList<>();
        for (SearchHit<Product> productSearchHit : search) {
            Product product = productSearchHit.getContent();
            products.add(product);
        }
        /**
         * 封装Page对象,参数1:具体数据, 参数2:分页条件对象, 参数3:总条数
         */
        PageImpl<Product> page = new PageImpl<>(products, pageable, search.getTotalHits());
        System.out.println("总条数:"+page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("当前页面数据:"+page.getContent());
    }
    

5、结果排序

  1. 在com.zzx.myes2.templatetest包下的TemplateTest类添加结果排序方法
    //结果排序
    @Test
    public void searchDocumentSort(){
        //1.确定查询方式
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        //2.构建查询条件
        //排序条件
        SortBuilder sortBuilder = SortBuilders.fieldSort("id").order(SortOrder.DESC);
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQueryBuilder).withSorts(sortBuilder).build();
        //3.查询
        SearchHits<Product> search = template.search(query, Product.class);
        //4.处理查询结果
        for (SearchHit<Product> productSearchHit : search) {
            Product product = productSearchHit.getContent();
            System.out.println(product);
        }
    }
    

总结:

  1. 1)使用Repository接口实现操作ElasticSearch,需要yml文件配置ES的主机和端口号,用一个接口去继承ElasticsearchRepository类,调用该类提供的方法即可。
    2)DSL实现的话,用一个接口去继承ElasticsearchRepository类,通过@Query注解编写DSL语句,调用@Query注解下的方法即可。
    3)按照规则命名方法查询,既不用编写DSL语句,也不用使用固定的方法,而是根据查询的需要按照规则命令该方法即可查询。命名以findBy开头。
    4)分页查询时,需要使用Pageable类。
    结果排序时,需要使用Sort类。
  2. 1)使用SpringDataES的ElasticsearchRestTemplate工具类操作索引时,需要先获取索引对象IndexOperations,再操作索引。
    2)ElasticsearchRestTemplate增加或修改文档用save方法,删除用delete,查询用search。
    复杂文档查询需要创建多条件查询构造器BoolQueryBuilder,通过往该构造器中添加查询条件即可,添加的方式有must、should、mustNot三种。
    3)分页查询文档,在构建查询条件时指定分页条件PageRequest对象,将查询结果和分页条件对象以及查询结果的总条数传入PageImpl对象中。
    4)对查询结果排序,使用SortBuilder构建排序条件,再添加到查询语句中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是SpringBoot整合elasticsearch的步骤: 1. 引入elasticsearch和spring-boot-starter-data-elasticsearch的依赖: ``` <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.12.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version>2.4.5</version> </dependency> ``` 2. 配置elasticsearch连接信息: ``` spring.data.elasticsearch.cluster-nodes=localhost:9200 ``` 3. 创建实体类: ``` @Document(indexName = "my_index") public class MyEntity { @Id private String id; private String name; // getter and setter } ``` 4. 创建es的Repository: ``` public interface MyRepository extends ElasticsearchRepository<MyEntity, String> { } ``` 5. 在service中使用Repository: ``` @Service public class MyService { @Autowired private MyRepository myRepository; public void save(MyEntity entity) { myRepository.save(entity); } public List<MyEntity> search(String name) { return myRepository.findByName(name); } } ``` 6. 在controller中调用service: ``` @RestController public class MyController { @Autowired private MyService myService; @PostMapping("/save") public void save(@RequestBody MyEntity entity) { myService.save(entity); } @GetMapping("/search") public List<MyEntity> search(@RequestParam String name) { return myService.search(name); } } ``` 这样就可以通过SpringBoot整合elasticsearch实现数据的增删改查了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值