【问题标题】:How spring data elasticsearch use offset and limit to queryspring data elasticsearch如何使用offset和limit进行查询
【发布时间】:2020-01-20 08:54:36
【问题描述】:

spring data elastisearch 如何使用 offset 和 limit 进行查询。我想使用偏移量和限制参数来查询页面。但是我找不到方法支持。例如:

    queryBuild.withPageable(PageRequest.of(pageIndex, pageSize));
    Page<Content> content = elasticsearchOperations.queryForPage(queryBuild.build(),Content.class);

应该没问题

但我找不到带有偏移量和限制的方法

    queryBuild.withPageable(PageRequest.of(offset, limit));

【问题讨论】:

    标签: spring-data-elasticsearch


    【解决方案1】:

    我有同样的问题,所以我实现了下面的类

    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
    
    public class OffsetLimitPageable implements Pageable {
    
        private int offset;
        private int page;
        private int size;
        private Sort sort = Sort.unsorted();
    
        protected OffsetLimitPageable(int offset, int page, int size) {
            if (offset < 0) {
                throw new IllegalArgumentException("Offset must not be less than zero!");
            }
    
            if (page < 0) {
                throw new IllegalArgumentException("Page index must not be less than zero!");
            }
    
            if (size < 1) {
                throw new IllegalArgumentException("Page size must not be less than one!");
            }
    
            this.offset = offset;
            this.page = page;
            this.size = size;
        }
    
        public static OffsetLimitPageable of(int offset, int page, int size) {
            return new OffsetLimitPageable(offset, page, size);
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#getPageNumber()
         */
        @Override
        public int getPageNumber() {
            return page;
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#getPageSize()
         */
        @Override
        public int getPageSize() {
            return size;
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#getOffset()
         */
        @Override
        public long getOffset() {
            return offset + page * size;
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#getSort()
         */
        @Override
        public Sort getSort() {
            return sort;
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#next()
         */
        public Pageable next() {
            return of(offset, page + 1, size);
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#previousOrFirst()
         */
        public Pageable previousOrFirst() {
            return hasPrevious() ? of(offset, page - 1, size) : first();
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#first()
         */
        public Pageable first() {
            return of(offset, 0, size);
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.data.domain.Pageable#hasPrevious()
         */
        public boolean hasPrevious() {
            return page > 0;
        }
    }
    

    而且,像这样使用

    queryBuild.withPageable(OffsetLimitPageable.of(offset, page, limit));
    

    【讨论】:

    • getPageNumber() 到底是干什么用的?当offset 大于0(即使page 为0)时,您在技术上不也有前一页吗?
    • Pageable接口需要此方法
    • 我了解到Pageable 也可以参与在 HTTP 响应中将有关 URL 的信息返回到下一页,因此它可能与此有关。无论哪种方式,您的实现都不能用于在第 0 页中查找 offset 之前的条目。对于这样的实现,当 offset > 0 时,对于第 0 页,它应该在 getPageSize() 和 0 中返回 offsetgetOffset()。页码甚至可能不需要从零开始,但这就是 PageRequest 所做的。我们只是不知道。
    【解决方案2】:

    spring-data-es(或任何 spring-data 项目)不支持此功能,因此您必须为 Pageable 接口提供自己的自定义实现

    如果您尝试使用存储库变体(扩展 ElasticsearchRepository&lt;...,...&gt;)并实现自己的,请查看 hereherehere

    然后按照您的说明执行查询,使用

    PageRequest p = new MyOwnPageRequest(offset, limit);
    SearchQuery sq = new NativeSearchQueryBuilder()
                .withQuery(matchAllQuery())
                .withPageable(p)
                .build();
    
    Page<SampleEntity> result = elasticsearchTemplate.queryForPage(sq, SampleEntity.class);
    

    【讨论】:

    • 感谢您的回答。我有个问题。 Spring-data-elasticsearch的源代码使用pageNumber和pageSize进行查询。如:Java if (query.getPageable().isPaged()) { startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); searchRequestBuilder.setSize(query.getPageable().getPageSize()); } 所以当offset=9,limit=10时,pageNumber和pageSize将没有对应的值。(无论pageSize=10和pageNumber=1还是0,startRecord都会出错)
    • @Michael 源代码现在好像变了。看看the latest code,你会看到它使用了偏移量:)
    • @ch271828n 我明白了。谢谢。
    猜你喜欢
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2021-04-21
    • 2021-05-17
    • 2013-12-20
    • 2015-05-07
    • 1970-01-01
    相关资源
    最近更新 更多