美文网首页
spring-data-elasticsearch使用searc

spring-data-elasticsearch使用searc

作者: 最小栗子 | 来源:发表于2022-10-07 20:57 被阅读0次

最近防疫项目用到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

源码位置:https://github.com/spring-projects/spring-data-elasticsearch/blob/4.2.x/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java

   /**
     * 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-elasticsearchspring-data-elasticsearch版本错误问题

如果你的pom文件中继承的spring-boot-starter-parent版本小于2.5.0,那么哪怕你引入的spring-boot-starter-data-elasticsearch版本是2.7.xspring-data-elasticsearch还是会低于4.2.x,导致Query类中是没有setSearchAfter()方法:

image.png
可以通过将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>
image.png

官方的版本对应关系图

附上传送地址:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.versions

image.png

相关文章

网友评论

      本文标题:spring-data-elasticsearch使用searc

      本文链接:https://www.haomeiwen.com/subject/tsvbartx.html