SpringBoot整合Elasticsearch-Spring Data Elasticsearch实现增删改查(三)

文章目录

  • 1. Spring Data Elasticsearch
  • 2. 创建项目
    • 2.1 添加依赖
    • 2.2 application.yml文件
    • 2.3 pojo类Student
    • 2.4 通过ElasticsearchRepository实现CRUD操作
      • 2.4.1 Repository 方法命名规范
      • 2.4.2 创建StuRepository接口
      • 2.4.3 在ES中创建Student索引
      • 2.4.4 实现新增/修改操作
      • 2.4.5 实现查询操作
      • 2.4.6 实现删除操作
      • 2.4.7 在ES中查看数据
    • 2.5 使用Criteria 构建查询-SearchOperations工具
      • 2.5.1 创建查询方法类StuSearcher
      • 2.5.2 实现数据查询

1. Spring Data Elasticsearch

Spring Data Elasticsearch 是 Elasticsearch 搜索引擎开发的解决方案。它提供:

模板对象,用于存储、搜索、排序文档和构建聚合的高级API。

例如,Repository 使开发者能够通过定义具有自定义方法名称的接口来表达查询。

2. 创建项目

2.1 添加依赖

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-elasticsearchartifactId>
        dependency>

或者
SpringBoot整合Elasticsearch-Spring Data Elasticsearch实现增删改查(三)_第1张图片

2.2 application.yml文件

spring:
  elasticsearch:
    rest:
      # 连接es主节点
      uris: 192.168.126.130:9200
logging:
  level:
    tracer: trace

logging.level.tracer=trace的作用是在控制台中显示底层的查询日志

2.3 pojo类Student

/**
 * ES的注解@Document,
 * indexName: student数据存储的位置,存在那个索引中
 * shards: 指定分片的数量 默认1
 * replicas: 指定副本的数量 默认1 
 * createIndex: 是否自动创建es索引 默认true
 * 分片和副本,我们在kibana上已经创建好了这里不用管
 * */

@Document(indexName = "students", shards=3, replicas =2)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    @Id //使用学生的学号作为索引ID
    private Long id;
    @Field(name="name") /**es索引中的属性名,对应实体类中的变量
                            相同可以不设置*/
    private String name;
    private Character gender;
    private String birthDate;
}

@Document注解
@Documnet注解对索引的参数进行设置, 上面把 Students 索引的分片数设置为3,副本数设置为2。

@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {
	//要连接的索引名称
    String indexName();

    /** @deprecated */
    @Deprecated
    String type() default "";

    boolean useServerConfiguration() default false;
	//默认分片数量
    short shards() default 1;
	//默认副本数量
    short replicas() default 1;

    String refreshInterval() default "1s";

    String indexStoreType() default "fs";
	//是否自动创建索引
    boolean createIndex() default true;

    VersionType versionType() default VersionType.EXTERNAL;
}

@Id注解
在 Elasticsearch 中创建文档时,使用 @Id 注解的字段作为文档的 _id 值
@Field注解
通过 @Field 注解设置字段的数据类型和其他属性。
name: 设置字段名
FieldType: 字段数据类型(默认Auto自动)

  • 文本类型 text 和 keyword
    1. text 类型会进行分词。
    2. keyword 不会分词。
  • analyzer 指定分词器
    1. 通过 analyzer 设置可以指定分词器,例如 ik_smart、ik_max_word 等。

SpringBoot整合Elasticsearch-Spring Data Elasticsearch实现增删改查(三)_第2张图片

2.4 通过ElasticsearchRepository实现CRUD操作

Spring Data 的 Repository 接口提供了一种声明式的数据操作规范,无序编写任何代码,只需遵循 Spring Data 的方法定义规范即可完成数据的 CRUD 操作。

ElasticsearchRepository 继承自 Repository,其中已经预定义了基本的 CURD 方法,我们可以通过继承 ElasticsearchRepository,添加自定义的数据操作方法。

2.4.1 Repository 方法命名规范

自定义数据操作方法需要遵循 Repository 规范(方法命名规范)

关键词 方法名 es查询
And findByNameAndPrice { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } }, { “query_string” : { “query” : “?”, “fields” : [ “price” ] } } ] } }}
Or findByNameOrPrice { “query” : { “bool” : { “should” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } }, { “query_string” : { “query” : “?”, “fields” : [ “price” ] } } ] } }}
Is findByName { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } } ] } }}
Not findByNameNot { “query” : { “bool” : { “must_not” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } } ] } }}
Between findByPriceBetween { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
LessThan findByPriceLessThan { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : false } } } ] } }}
LessThanEqual findByPriceLessThanEqual { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
GreaterThan findByPriceGreaterThan { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : false, “include_upper” : true } } } ] } }}
GreaterThanEqual findByPriceGreaterThan { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : true, “include_upper” : true } } } ] } }}
Before findByPriceBefore { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
After findByPriceAfter { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : true, “include_upper” : true } } } ] } }}
Like findByNameLike { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?*”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
StartingWith findByNameStartingWith { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?*”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
EndingWith findByNameEndingWith { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “*?”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
Contains/Containing findByNameContaining { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
In (when annotated as FieldType.Keyword) findByNameIn(Collectionnames) { “query” : { “bool” : { “must” : [ {“bool” : {“must” : [ {“terms” : {“name” : ["?","?"]}} ] } } ] } }}
In findByNameIn(Collectionnames) { “query”: {“bool”: {“must”: [{“query_string”:{“query”: “”?" “?”", “fields”: [“name”]}}]}}}
NotIn (when annotated as FieldType.Keyword) findByNameNotIn(Collectionnames) { “query” : { “bool” : { “must” : [ {“bool” : {“must_not” : [ {“terms” : {“name” : ["?","?"]}} ] } } ] } }}
NotIn findByNameNotIn(Collectionnames) {“query”: {“bool”: {“must”: [{“query_string”: {“query”: “NOT(”?" “?”)", “fields”: [“name”]}}]}}}
Near findByStoreNear Not Supported Yet !
True findByAvailableTrue { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “true”, “fields” : [ “available” ] } } ] } }}
False findByAvailableFalse { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “false”, “fields” : [ “available” ] } } ] } }}
OrderBy findByAvailableTrueOrderByNameDesc { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “true”, “fields” : [ “available” ] } } ] } }, “sort”:[{“name”:{“order”:“desc”}}] }

2.4.2 创建StuRepository接口

/**
 * Repository规范,只要实现Repository接口,就可以访问数据,具体代码不需要自己完成(方法名的创建需要满足规范)
 * spring data 会自动创建动态代理对象
 *  访问的数据类型, 索引的id类型
 * */
public interface StuRepository extends ElasticsearchRepository<Student,Long> {

    //根据name搜索
    List<Student> findByName(String name);

    //根据nema或者birthDate搜索
    List<Student> findByNameOrBirthDate(String name , String birthDate, Pageable pageable);
}

2.4.3 在ES中创建Student索引

也可以在Student类的@Document注解上添加参数, 自动创建索引

PUT /students
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2,
    "index.max_ngram_diff":30,
    "analysis": {
      "analyzer": {
        "ngram_analyzer": {
          "tokenizer": "ngram_tokenizer"
        }
      },
      "tokenizer": {
        "ngram_tokenizer": {
          "type": "ngram",
          "min_gram": 1,
          "max_gram": 30,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id": {
        "type": "long"
      },
      "name": {
        "type": "text",
        "analyzer": "ngram_analyzer"
      },
      "gender": {
        "type": "keyword"
      },
      "birthDate": {
        "type": "date",
        "format": "yyyy-MM-dd"
      }
    }
  }
}

2.4.4 实现新增/修改操作

  @Autowired
  private StuRepository stuRepository;
  //新增数据
  @Test
  public void test(){
      Student s1 = new Student(9527L,"唐伯虎",'男',"2021-07-12");
      Student s2 = new Student(9528L,"华夫人",'女',"2021-03-22");
      stuRepository.save(s1);
      stuRepository.save(s2);

  }

注入接口(代理)对象
直接调用接口自带save方法即可新增/修改

2.4.5 实现查询操作

Repository自带的方法查询


@Test
    void test3(){
        //查询单个学生
        Optional<Student> s1 = stuRepository.findById(9527L);
        Student student = s1.get();
        System.out.println(student);
        
        
        //查询所有数据
        Iterable<Student> it = stuRepository.findAll();
        for (Student s2: it){
            System.out.println(s2);
        }
    }

自定义方法实现查询

	//根据姓名搜索,通过自己创建的接口函数
    @Test
    void test5(){
        List<Student> list = stuRepository.findByName("唐");
        for (Student s:list){
            System.out.println(s);
        }
    }

    //通过name或者birthdate查询
    //加分页参数
    @Test
    void test6(){
        //page 从0开始
        PageRequest page = PageRequest.of(1, 1);
        List<Student> list = stuRepository.findByNameOrBirthDate("虎", "2021-03-22", page);
        for (Student student : list){
            System.out.println(student);
        }
    }

2.4.6 实现删除操作

Id在ES中的类型是long类型,这里参数需要是long类型的

	//删除数据
    @Test
    void test4(){
        stuRepository.deleteById(9527L);
    }

2.4.7 在ES中查看数据

SpringBoot整合Elasticsearch-Spring Data Elasticsearch实现增删改查(三)_第3张图片

2.5 使用Criteria 构建查询-SearchOperations工具

使用 SearchOperations 工具执行一些更复杂的查询,这些查询操作接收一个 Query 对象封装的查询操作。

Spring Data Elasticsearch 中的 Query 有三种:

  • CriteriaQuery
  • StringQuery
  • NativeSearchQuery

多数情况下,CriteriaQuery 都可以满足我们的查询求。

2.5.1 创建查询方法类StuSearcher

//通过Criteria 构建查询,通过API进行搜索
@Component
public class StuSearcher {

    @Autowired
    private ElasticsearchOperations op;
    //根据birthDate搜索,
    public List<Student> findByBirthdate(String birthDate){
        //用Criteria设置搜索条件
        Criteria c1 = new Criteria("birthDate").is(birthDate);
        //有分页参数,设置分页参数,没有null值
        return search(c1,null);
    }

    //用birthDate的范围搜索
    //搜索条件
    public List<Student> findByBirthdate(String ge, String le) {
        //用Criteria构建搜索条件between(),在一定范围内搜索
        Criteria c = new Criteria("birthDate").between(ge, le);
        //设置分页对象
        PageRequest page = PageRequest.of(0, 10);
        return search(c,page);
    }
    
    //构建搜索方式search方法
    public List<Student> search(Criteria c,PageRequest page){
        //搜索条件封装到Query中
        CriteriaQuery q = new CriteriaQuery(c);

        //有分页参数,设置分页参数
        if(page!=null){
            q.setPageable(page);
        }
        //执行搜索
        SearchHits<Student> hits = op.search(q, Student.class);

        //基本的集合api频繁操作
//        ArrayList list = new ArrayList<>();
//        for (SearchHit h: hits){
//            Student stu = h.getContent();
//            list.add(stu);
//        }

        //集合的流操作代码
        List<Student> list = hits.stream().map(SearchHit::getContent).collect(Collectors.toList());
        return list;

    }
}

2.5.2 实现数据查询

    @Autowired
    private StuSearcher stuSearcher;
    
    //根据Searcher,搜索birthDate查询
    @Test
    void test7(){
        List<Student> byBirthdate = stuSearcher.findByBirthdate("2021-09-11");
        System.out.println(byBirthdate);
    }

	//根据Searcher,查询birthDate一定范围内的数据
    @Test
    void test8(){
        List<Student> list = stuSearcher.findByBirthdate("2021-06-16");
        for (Student s:list){
            System.out.println(s);
        }
    }

你可能感兴趣的:(Elasticsearch,elasticsearch)