How to convert SearchHits<T> return type to Page<T> return type in spring data elasticsearch 4.0

2.7k views Asked by At

I have a spring boot application connecting to an ElasticSearch cluster and I'm performing the following operation on it:

@Autowired
private ElasticsearchOperations operations;

public Page<Metadata> search(Request request){
    Query query = this.queryBuilder(request);
    SearchHits<Metadata> hits = operations.search(query, Metadata.class);
    \\ some code to convert SearchHits<Metadata> to Page<Metadata> type
 }

Metadata is my custom entity and query builder is another function I've defined that returns an elasticsearch query type at runtime. The issue is, I need to page this incoming data before returning it. I've looked through the entire official documentation for spring data elasticsearch but haven't found any examples for paging results. In fact, the only example of paging I could find anywhere on the internet was using a spring repository search method, which was something like this,

Page<Metadata> page = repository.search(query, PageRequest.of(0,1));

but that method is now deprecated in the 4.x version of the package. The query I'm using is constructed dynamically by another function (the queryBuilder function) and it depends on incoming request parameters so defining methods on the repository interface is out of the questions as it would require me to define methods for every single combination of parameters and checking which one to use with if-else conditional blocks each time. Is there any way to either return a Page <T> type from the ElasticSearchOperations interface methods (the official documentation claims a SearchPage <T> type as one of the types available for return values, but none of the suggested methods returns that type) or alternatively is there any way to convert SearchHits<T> to type Page<T>.

Any help is much appreciated.

2

There are 2 answers

2
Kushal Chordiya On

fortunately I found an answer to this question, thanks to this questions asked earlier

As mentioned over there, the query parameter passed to the search method has a setPageable method. So, the code will now look somewhat like

public SearchPage<Metadata> search(Request request){
    Query query = this.queryBuilder(request);
    query.setPageable(PageRequest.of(PageNumber,PageSize));
    SearchHits<Metadata> hits = operations.search(query, Metadata.class);
    return SearchHitSupport.searchPageFor(hits, query.getPageable());
}

As suggested by a commenter, SearchPage and Page are both interfaces, so changing the return type of the method is not necessary

0
Md. Mahmud Hasan On

I have done this in the following way:

SearchPage<YourClass> page = SearchHitSupport.searchPageFor(searchHits, query.getPageable());
return (Page)SearchHitSupport.unwrapSearchHits(page);