Как установить нулевой размер результата в весеннем эластичном поиске данных

Рассмотрим следующий запрос elasticsearch:

{
  "query": {"match_all": {}},
  "size": 0, 
  "aggs": {
      "Terms": { "terms": { "field":"fileName" }
      }
   }
}

Здесь меня просто интересует агрегация, а не документы. Вот почему я установил size:0, и он работает, как и ожидалось. Однако я не могу добиться того же с spring-data. Пример кода:

PageRequest page = new PageRequest(0, 0);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withIndices(indexName).withTypes(typeName)
                .withQuery(queryBuilder).withAggregation(aggsBuilder)
                .withPageable(pageable).build();

Затем этот конструктор PageRequest выдает исключение, которое исходит от его родителя:

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

Вопрос: Есть ли способ в весенних данных ограничить размер документа до нуля?


person blackSmith    schedule 13.05.2016    source источник
comment
@Mohsin Husen: мне нужна твоя помощь здесь!   -  person blackSmith    schedule 13.05.2016
comment
Какую версию ES и Spring Data ES вы используете?   -  person Val    schedule 13.05.2016
comment
ES версии 1.3.4 и spring-data-es 1.1.4   -  person blackSmith    schedule 16.05.2016


Ответы (5)


Мы можем определить пустой класс реализации страничного интерфейса, например:

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

Использовать:

    SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(queryBuilder)
            .withIndices(indexName).withTypes(typeName)
            .addAggregation(aggsBuilder)
            .withPageable(EmptyPage.INSTANCE)
            .build();

Результат:

{
  "aggregations": { ... },
  "from": 0,
  "query": { ... },
  "size": 0
}
person Alex    schedule 21.03.2017

Если вы используете ES 1.x, вы можете пропустить Pageable и вместо этого указать тип поиска COUNT.

SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withIndices(indexName).withTypes(typeName)
            .withQuery(queryBuilder).withAggregation(aggsBuilder)
            .withSearchType(SearchType.COUNT).build();

Начиная с ES 2.x, SearchType.COUNT будет объявлен устаревшим и больше не будет доступен, но для нужд ES 1.x это должно сработать.

Обратите внимание, что существует такая же потребность и для других пользователей, но проблема остается открытой.

person Val    schedule 13.05.2016
comment
Может быть, вы не поняли мой вопрос или я не понял сути вашего ответа. Я вижу, что withSearchType(SearchType.COUNT) устанавливает тип поиска, но где я буду помещать его значение в 0? - person blackSmith; 16.05.2016
comment
Вы этого не сделаете, count search type никогда не отправит вам обратно документы, только результаты агрегирования. - person Val; 16.05.2016
comment
Что делать для ES 5.x, так как SearchType.COUNT удален? - person Pratz; 15.09.2017
comment
@Pratz Я думаю, вам, возможно, придется использовать страницу размера 1: PageRequest(0, 1) - person Val; 15.09.2017

Это немного поздно, но может быть полезно для будущих разработчиков. Для меня путь состоял в том, чтобы определить новый класс PageRequest, который реализует org.springframework.data.domain.Pageable и напоминает org.springframework.data.domain.PageRequest, но не имеет ограничений AbstractPageRequest по размеру.
Затем вы можете передать его своему компоновщику.

person Laabidi Raissi    schedule 08.03.2017
comment
Я согласен. Просто используйте PagingAndSortingRepository в своем интерфейсе, который позволяет запрашивать эластичный поиск. И вернитесь на страницу ‹yourClass›. - person DOUBL3P; 18.07.2017

Начиная с Spring Data Elasticsearch 4.0, NativeSearchQuery, StringQuery и CriteriaQuery имеют метод setMaxResults(Integer maxResults)

поэтому запрос будет

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

searchQuery.setMaxResults(0);

Метод setMaxResults() возвращает void, поэтому его нельзя использовать с синтаксисом компоновщика.

Это добавит "size":0 вверху объекта запроса.

person muttonUp    schedule 17.04.2021

Я думаю, что вы хотите установить "size": 0 в коде?

Пейджинг не поддерживается в агрегатах, поэтому PageRequest не будет развлекаться. Ошибка в том, что ограничение страницы не может быть равно 0. Вам нужно:

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                        .withIndices(indexName).withTypes(typeName)
                        .withQuery(queryBuilder)
                        .withAggregation(aggsBuilder.size(0)) //set the size with AggregationBuilders
                        .withSearchType(SearchType.COUNT)                        
                        .build();
person ystark    schedule 16.05.2016
comment
Во-первых: вы вообще не поняли мой вопрос. Во-вторых, вы редактируете мой вопрос, чтобы выразить другое значение, на которое вы отвечаете! Я не виню тебя, но это нехорошо. Вэл ответил на него правильно, хотя я еще не проверил. - person blackSmith; 16.05.2016