我正在尝试对某些条件过滤后的值进行汇总。我正在使用spring数据的ElasticSearchTemplate.query()方法也执行查询并在结果提取器中获取结果。我正确地找到了匹配(即应用了过滤器,并且仅检索了与这些值匹配的文档。)。但是,汇总是在所有文档上执行的。我认为汇总应仅应用于过滤后的值。以下是我正在使用的代码:
SearchQuery query = //get the query SearchResponse hits = template.query(query, new ResultsExtractor<SearchResponse>() { @Override public SearchResponse extract(SearchResponse response) { return response; } });
为了进一步调试问题,我编写了代码来执行查询,而不是使用spring数据。以下是代码:
SearchRequestBuilder builder = esSetup.client().prepareSearch("document"); builder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), query.getFilter())); builder.addFields(query.getFields().toArray(new String[query.getFields().size()])); for(AbstractAggregationBuilder aggregation : query.getAggregations()){ builder.addAggregation(aggregation); } SearchResponse response = builder.get();
令我惊讶的是,此查询正确执行,并且对聚合也应用了过滤器。为了进一步分析,我遍历了elasticsearchtemplate的代码,发现它使用setPostFilter方法来设置过滤器。然后,我修改了代码以这种方式设置过滤器:
setPostFilter
SearchRequestBuilder builder = esSetup.client().prepareSearch("document"); // builder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), query.getFilter())); builder.setPostFilter(query.getFilter()); builder.addFields(query.getFields().toArray(new String[query.getFields().size()])); for(AbstractAggregationBuilder aggregation : query.getAggregations()){ builder.addAggregation(aggregation); } SearchResponse response = builder.get();
当我执行以上代码时,它表现出与spring数据相同的行为!(即,过滤器应用于查询,但未应用于汇总。这是spring数据的错误吗?如果不是,那么,还有其他方法可用来以我想要的方式检索数据吗?
提前致谢。
此行为是设计使然在Elasticsearch中。
用非常简单的话来说,聚合和后过滤器的输入是query与请求主体部分匹配的文档集。因此,汇总不会应用于过滤后的文档。
query
但是,如果您确实希望将聚合应用于过滤后的文档,请“将过滤器移至该query部分内”,即使用过滤后的查询。现在,该query部分的输出将是过滤后的文档集,并且汇总将按预期应用于它们。
因此,根据您的要求,请使用过滤查询而不是后过滤器。