Michael
Michael

Reputation: 41

How spring data elasticsearch use offset and limit to query

How spring data elastisearch use offset and limit to query. I want to use offset and limit param to query page.But I can not find methods support. For Example:

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

it could be ok

But I can not found method with offset and limit

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

Upvotes: 4

Views: 5821

Answers (2)

LuisComS
LuisComS

Reputation: 592

I have the same problem, so I implemented the following class

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;
    }
}

And, use like this

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

Upvotes: 3

a.k
a.k

Reputation: 1203

This is not supported in spring-data-es (or in ANY spring-data project), so you'll have to provide your own custom implementation for the Pageable interface

Take a look here or here and here if you attempt to use the repository variant (extending ElasticsearchRepository<...,...>) and implement your own.

Then perform the query just as you noted, with

PageRequest p = new MyOwnPageRequest(offset, limit);
SearchQuery sq = new NativeSearchQueryBuilder()
            .withQuery(matchAllQuery())
            .withPageable(p)
            .build();

Page<SampleEntity> result = elasticsearchTemplate.queryForPage(sq, SampleEntity.class);

Upvotes: 1

Related Questions