spring-data-elasticsearch使用search_after
最近防疫项目用到es做人员扫码快速检索能力,且es是集群部署,所以在深度分页这一块采用search_after的方式,项目采用spring-cloud开发,所以自然考虑使用spring-data-elasticsearch来操作es,过程中遇到一些坑,分享出来希望对大家有些帮助。
当然,先说正常的使用。 引入依赖,这里直接使用starter 1 2 3 4 5 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-elasticsearch</artifactId > <version > 2.7.4</version > </dependency >
application.properties 1 2 3 4 5 6 7 8 9 spring.application.name =springdataesdemo spring.elasticsearch.rest.uris =172.29.0.22:31853 spring.elasticsearch.rest.connection-timeout =1000 spring.elasticsearch.rest.password =123456 spring.elasticsearch.rest.username =elastic server.port =8082
实体类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package org.example.springdataelasticsearch.entity;import org.springframework.data.annotation.Id;import org.springframework.data.elasticsearch.annotations.Document;import org.springframework.data.elasticsearch.annotations.Field;@Data @Document(indexName = "record", createIndex = false) public class Record { @Id private String id; private String username; @Field(name = "create_time") private String createTime;
单元测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package org.example.springdataelasticsearch;import org.example.springdataelasticsearch.entity.Record;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.data.domain.PageRequest;import org.springframework.data.domain.Sort;import org.springframework.data.elasticsearch.core.ElasticsearchOperations;import org.springframework.data.elasticsearch.core.SearchHit;import org.springframework.data.elasticsearch.core.SearchHits;import org.springframework.data.elasticsearch.core.query.Query;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;@SpringBootTest public class RecordTest { @Autowired private ElasticsearchOperations operations; @Test void searchAfter () { Query query = Query.findAll(); query.setPageable(PageRequest.of(0 , 3 )); query.addSort(Sort.by(Sort.Direction.ASC, "create_time" )); List<Object> searchAfter = null ; List<Record> foundEntities = new ArrayList <>(); int index = 0 ; do { query.setSearchAfter(searchAfter); SearchHits<Record> searchHits = operations.search(query, Record.class); if (index++ == 10 || searchHits.getSearchHits().isEmpty()){ break ; } foundEntities.addAll(searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList())); searchAfter = searchHits.getSearchHit((int ) (searchHits.getSearchHits().size() - 1 )).getSortValues(); }while (true ); System.out.println(foundEntities); System.out.println(searchAfter); } }
至此翻页就可以正常使用了
下面是一些踩坑点 1.通过观察spring-data-elasticsearch
的源码可以知道search_after
能力在4.2
版本才开始支持,所以此版本之前Query
类中是没有setSearchAfter()
方法的,如果使用的是spring-boot-starter-data-elasticsearch
,那要注意其中的spring-data-elasticsearch
版本有没有到达4.2
。 源码位置:https://github.com/spring-projects/spring-data-elasticsearch/blob/4.2.x/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java
1 2 3 4 5 6 7 8 void setSearchAfter (@Nullable List<Object> searchAfter) ;
2.与Spring Boot版本对应错误导致spring-boot-starter-data-elasticsearch
中spring-data-elasticsearch
版本错误问题 如果你的pom
文件中继承的spring-boot-starter-parent
版本小于2.5.0
,那么哪怕你引入的spring-boot-starter-data-elasticsearch
版本是2.7.x
,spring-data-elasticsearch
还是会低于4.2.x
,导致Query
类中是没有setSearchAfter()
方法: 可以通过将spring-boot-starter-parent
的版本升级到2.5.x
来解决这个问题,如果你的项目模块较多,或者什么原因升级版本有些麻烦,那么可以通过显示的添加指定版本的依赖来解决这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-elasticsearch</artifactId > <version > 2.7.4</version > <exclusions > <exclusion > <artifactId > spring-data-elasticsearch</artifactId > <groupId > org.springframework.data</groupId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.data</groupId > <artifactId > spring-data-elasticsearch</artifactId > <version > 4.4.3</version > <scope > compile</scope > </dependency > <dependency > <groupId > org.springframework.data</groupId > <artifactId > spring-data-commons</artifactId > <version > 2.7.3</version > </dependency >
官方的版本对应关系图 附上传送地址:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.versions