最近防疫项目用到es做人员扫码快速检索能力,且es是集群部署,所以在深度分页这一块采用search_after的方式,项目采用spring-cloud开发,所以自然考虑使用spring-data-elasticsearch来操作es,过程中遇到一些坑,分享出来希望对大家有些帮助。
当然,先说正常的使用。
引入依赖,这里直接使用starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.7.4</version>
</dependency>
application.properties
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
实体类
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;
单元测试
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
。
/**
* Sets the setSearchAfter objects for this query.
*
* @param searchAfter the setSearchAfter objects. These are obtained with {@link SearchHit#getSortValues()} from a
* search result.
* @since 4.2
*/
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
来解决这个问题,如果你的项目模块较多,或者什么原因升级版本有些麻烦,那么可以通过显示的添加指定版本的依赖来解决这个问题:
<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

网友评论