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

1. Spring Data Elasticsearch

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

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

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

2. 创建项目

2.1 添加依赖

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

或者
在这里插入图片描述

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 等。

在这里插入图片描述

2.4 通过ElasticsearchRepository实现CRUD操作

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

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

2.4.1 Repository 方法命名规范

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

关键词方法名es查询
AndfindByNameAndPrice{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } }, { “query_string” : { “query” : “?”, “fields” : [ “price” ] } } ] } }}
OrfindByNameOrPrice{ “query” : { “bool” : { “should” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } }, { “query_string” : { “query” : “?”, “fields” : [ “price” ] } } ] } }}
IsfindByName{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } } ] } }}
NotfindByNameNot{ “query” : { “bool” : { “must_not” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } } ] } }}
BetweenfindByPriceBetween{ “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
LessThanfindByPriceLessThan{ “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : false } } } ] } }}
LessThanEqualfindByPriceLessThanEqual{ “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
GreaterThanfindByPriceGreaterThan{ “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : false, “include_upper” : true } } } ] } }}
GreaterThanEqualfindByPriceGreaterThan{ “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : true, “include_upper” : true } } } ] } }}
BeforefindByPriceBefore{ “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
AfterfindByPriceAfter{ “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : true, “include_upper” : true } } } ] } }}
LikefindByNameLike{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?*”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
StartingWithfindByNameStartingWith{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?*”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
EndingWithfindByNameEndingWith{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “*?”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
Contains/ContainingfindByNameContaining{ “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” : ["?","?"]}} ] } } ] } }}
InfindByNameIn(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” : ["?","?"]}} ] } } ] } }}
NotInfindByNameNotIn(Collectionnames){“query”: {“bool”: {“must”: [{“query_string”: {“query”: “NOT(”?" “?”)", “fields”: [“name”]}}]}}}
NearfindByStoreNearNot Supported Yet !
TruefindByAvailableTrue{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “true”, “fields” : [ “available” ] } } ] } }}
FalsefindByAvailableFalse{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “false”, “fields” : [ “available” ] } } ] } }}
OrderByfindByAvailableTrueOrderByNameDesc{ “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “true”, “fields” : [ “available” ] } } ] } }, “sort”:[{“name”:{“order”:“desc”}}] }

2.4.2 创建StuRepository接口

/**
 * Repository规范,只要实现Repository接口,就可以访问数据,具体代码不需要自己完成(方法名的创建需要满足规范)
 * spring data 会自动创建动态代理对象
 * <Student,Long> 访问的数据类型, 索引的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中查看数据

在这里插入图片描述

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<Student> list = new ArrayList<>();
//        for (SearchHit<Student> 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);
        }
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以按照以下步骤使用 Spring Boot 和 Elasticsearch 实现增删改查的功能: 1. 添加依赖:在你的 Spring Boot 项目的 pom.xml 文件中,添加 Elasticsearch 相关的依赖。例如: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2. 配置 Elasticsearch:在你的 application.properties 或 application.yml 文件中,配置 Elasticsearch 的连接信息。例如: ```yaml spring.data.elasticsearch.cluster-nodes=localhost:9200 ``` 3. 创建实体类:创建一个代表你要操作的数据的实体类,并使用注解来映射到 Elasticsearch 中的索引和类型。例如: ```java import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; @Document(indexName = "your_index_name", type = "your_type_name") public class YourEntity { @Id private String id; private String name; // 其他属性和方法 } ``` 4. 创建数据访问接口:创建一个继承自 ElasticsearchRepository 的数据访问接口,该接口提供了一些基本的 CRUD 方法。例如: ```java import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; public interface YourEntityRepository extends ElasticsearchRepository<YourEntity, String> { // 可以根据需要添加自定义的查询方法 } ``` 5. 编写业务逻辑:在你的服务类中使用 YourEntityRepository 来进行相关的数据操作。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class YourService { @Autowired private YourEntityRepository repository; public YourEntity save(YourEntity entity) { return repository.save(entity); } public void delete(String id) { repository.deleteById(id); } public Iterable<YourEntity> findAll() { return repository.findAll(); } // 可以根据需要添加其他的查询方法和业务逻辑 } ``` 这样,你就可以通过调用 YourService 中的方法来实现Elasticsearch增删改查操作了。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值