blackSmith
blackSmith

Reputation: 3154

How to set result size zero in spring data elasticsearch

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 ?

Upvotes: 7

Views: 10506

Answers (6)

Cugomastik
Cugomastik

Reputation: 1009

Found this on link

It would be useful to have a "withMaxResults" method to NativeSearchQueryBuilder for specifying the maxResults on the built Query. This is common for aggregation queries where search hits are not needed.

Having the builder method for setting maxResults is a minor ergonomic improvement, e.g.

NativeSearchQuery searchQuery = NativeSearchQueryBuilder()
    .withQuery(matchAllQuery())
    .addAggregation(terms("examples").field("example"))
    .withMaxResults(0)
    .build();

Upvotes: 2

muttonUp
muttonUp

Reputation: 6717

From Spring Data Elasticsearch 4.0 on, NativeSearchQuery, StringQuery and CriteriaQuery have a method setMaxResults(Integer maxResults)

so the query would be

NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withIndices(indexName).withTypes(typeName)
                .withQuery(queryBuilder).withAggregation(aggsBuilder)
                .build();

searchQuery.setMaxResults(0);

The setMaxResults() method returns void so can't be used with the builder syntax

This will add "size":0 at the top of the request object

Upvotes: 6

Alex
Alex

Reputation: 378

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
}

Upvotes: 6

Laabidi Raissi
Laabidi Raissi

Reputation: 3333

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.

Upvotes: 1

ygh
ygh

Reputation: 595

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();

Upvotes: -1

Val
Val

Reputation: 217274

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.

Upvotes: 3

Related Questions