如何在 spring 数据 elasticsearch 中将结果大小设置为零

How to set result size zero in spring data 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;
}

问题:spring 数据中是否有任何方法可以将文档大小限制为零?

如果您使用的是 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 需要,这应该可以完成工作。

请注意,其他用户也有 similar need,但问题仍未解决。

我想你想要的是在代码中设置"size": 0

聚合中不支持分页,所以PageRequest不予受理。报错是因为page limit不能为0,你需要的是:

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                        .withIndices(indexName).withTypes(typeName)
                        .withQuery(queryBuilder)
                        .withAggregation(aggsBuilder.size(0)) //set the size with AggregationBuilders
                        .withSearchType(SearchType.COUNT)                        
                        .build();

这有点晚了,但可能对未来的开发人员有用。我的方法是定义一个新的 class PageRequest 来实现 org.springframework.data.domain.Pageable 并且类似于 org.springframework.data.domain.PageRequest 但没有 AbstractPageRequest 大小的限制。
然后你可以将它传递给你的构建器。

我们可以定义空的可分页接口实现class,像这样:

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
}

从Spring Data Elasticsearch 4.0开始,NativeSearchQueryStringQueryCriteriaQuery有一个方法setMaxResults(Integer maxResults)

所以查询将是

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

searchQuery.setMaxResults(0);

setMaxResults() 方法 returns void 所以不能与构建器语法一起使用

这将在请求对象的顶部添加"size":0

link

上找到这个

为 NativeSearchQueryBuilder 提供一个“withMaxResults”方法以指定构建查询的 maxResults 会很有用。这对于不需要搜索命中的聚合查询很常见。

使用构建器方法来设置 maxResults 是一个较小的人体工程学改进,例如

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