Consider the following elasticsearch query :
{
"query": {"match_all": {}},
"size": 0,
"aggs": {
"Terms": { "terms": { "field":"fileName" }
}
}
}
Here I'm just interested in the aggregation and not in the documents. That's why I set size:0
and it works as expected. However I'm unable to achieve the same with spring-data
. Code sample :
PageRequest page = new PageRequest(0, 0);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices(indexName).withTypes(typeName)
.withQuery(queryBuilder).withAggregation(aggsBuilder)
.withPageable(pageable).build();
This PageRequest
constructor throws an exception then, which is from its parent:
public AbstractPageRequest(int page, int size) {
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.page = page;
this.size = size;
}
Question : Is there any way in spring data to limit document size to zero ?
We can define empty pageable interface implementation class, like this:
public static class EmptyPage implements Pageable {
public static final EmptyPage INSTANCE = new EmptyPage();
@Override
public int getPageNumber() {
return 0;
}
@Override
public int getPageSize() {
return 0;
}
@Override
public int getOffset() {
return 0;
}
@Override
public Sort getSort() {
return null;
}
@Override
public Pageable next() {
return null;
}
@Override
public Pageable previousOrFirst() {
return null;
}
@Override
public Pageable first() {
return null;
}
@Override
public boolean hasPrevious() {
return false;
}
}
Use:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withIndices(indexName).withTypes(typeName)
.addAggregation(aggsBuilder)
.withPageable(EmptyPage.INSTANCE)
.build();
Result:
{
"aggregations": { ... },
"from": 0,
"query": { ... },
"size": 0
}
If you're using ES 1.x, what you can do is leave out the Pageable
and specify the search type COUNT
instead.
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices(indexName).withTypes(typeName)
.withQuery(queryBuilder).withAggregation(aggsBuilder)
.withSearchType(SearchType.COUNT).build();
As of ES 2.x, SearchType.COUNT
will be deprecated and not available anymore, but for ES 1.x needs this should do the job.
Note that there's a similar need for other users, too, but the issue is still open.
This is a bit late, but may be of use for future developers. The way for me was to define a new class PageRequest
that implements org.springframework.data.domain.Pageable
and the resembles org.springframework.data.domain.PageRequest
but does not have constraints of AbstractPageRequest
on size.
Then you can pass it to your builder.
I think what you want is to set "size": 0
in code?
Paging is not supported in aggregations, so the PageRequest
will not be entertained. The error is because page limit cannot be 0. What you need is:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices(indexName).withTypes(typeName)
.withQuery(queryBuilder)
.withAggregation(aggsBuilder.size(0)) //set the size with AggregationBuilders
.withSearchType(SearchType.COUNT)
.build();