【问题标题】:How to set result size zero in spring data elasticsearch如何在弹簧数据弹性搜索中将结果大小设置为零
【发布时间】:2016-09-09 12:22:55
【问题描述】:

考虑以下弹性搜索查询:

{
  "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 数据中有没有办法将文档大小限制为零?

【问题讨论】:

  • @Mohsin Husen:我需要你的帮助!
  • 你使用的是哪个版本的 ES 和 Spring Data ES?
  • ES 版本 1.3.4 和 spring-data-es 1.1.4

标签: java elasticsearch spring-data-elasticsearch


【解决方案1】:

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

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
}

【讨论】:

    【解决方案2】:

    如果您使用的是 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,但问题仍然存在。

    【讨论】:

    • 可能是您没有收到我的问题,或者我在您的回答中遗漏了要点。我看到 withSearchType(SearchType.COUNT) 设置了一个搜索类型,但是我将把它的值放在哪里 0 ?
    • 你不会,count search type 永远不会给你发回文件,只会给你汇总结果。
    • 删除 SearchType.COUNT 后,ES 5.x 该怎么办?
    • @Pratz 我认为您可能必须使用大小为 1 的页面:PageRequest(0, 1)
    【解决方案3】:

    从 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() 方法返回 void,因此不能与构建器语法一起使用

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 我同意你的看法。只需在界面中使用 PagingAndSortingRepository 即可请求弹性搜索。并返回页面 .
      【解决方案5】:

      我想你想要的是在代码中设置"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();
      

      【讨论】:

      • 首先:你根本没有得到我的问题。其次,您编辑我的问题以表达您正在回答的另一个含义!我不怪你,但这并不好。虽然我还没有验证,但 Val 已经正确回答了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      • 2017-01-03
      • 2019-05-02
      • 1970-01-01
      • 2014-06-17
      • 2019-06-09
      相关资源
      最近更新 更多