本文介绍了弹出数据ElastiSearch与过滤器的聚合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对某些条件过滤的值执行聚合。我使用弹簧数据的ElasticSearchTemplate.query()方法也执行查询,并在结果提取器中获取结果。
我正在获得命中(即应用过滤器,仅检索与这些值匹配的文档)。但是,所有文档都执行聚合。我认为聚合应该仅应用于过滤值。以下是我使用的代码:

  SearchQuery query = //获取查询
SearchResponse hits = template.query (query,new ResultsExtractor< SearchResponse>(){
@Override
public SearchResponse extract(SearchResponse response){
return response;
}
});

为了进一步调试问题,我写了代码来执行查询而不是使用弹簧数据。以下是代码:

  SearchRequestBuilder builder = esSetup.client()。prepareSearch(document); 
builder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),query.getFilter()));

builder.addFields(query.getFields()。toArray(new String [query.getFields()。size()])); (AbstractAggregationBuilder聚合:query.getAggregations())
{
builder.addAggregation(聚合);
}
SearchResponse response = builder.get();

令我惊讶的是,此查询正确执行,过滤器也应用于聚合。为了进一步分析,我经历了elasticsearchtemplate的代码,发现它使用 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()])); (AbstractAggregationBuilder聚合:query.getAggregations())
{
builder.addAggregation(聚合);
}
SearchResponse response = builder.get();

当我执行上面的代码,它显示与spring数据相同的行为! (即过滤器应用于查询而不是聚合)
这是一个弹簧数据的错误吗?如果没有,那么我有什么其他方法可以使用我想要的方式来检索数据? p>

提前感谢

解决方案

这种行为是在Elasticsearch中设计的。



简单来说,输入到聚合和后置过滤器是与查询部分匹配的文档集请求主体,因此聚合不会应用于过滤的文档。



但是,如果要将聚合应用于过滤的文档,请将过滤器内的查询部分,即使用。现在输出的查询部分将是过滤的文档集合,并且聚合将按预期应用于它们。 / p>

所以根据您的要求,使用过滤的查询而不是后置过滤器。


I am trying to perform aggregations on values filtered by some conditions. I am using ElasticSearchTemplate.query() method of spring data too execute query and get the results in result extractor.I am getting the hits correctly (i.e. filters are applied and docs matching those values are only retrieved.). However, aggregations are performed on all the docs. I believe aggregations should be applied to filtered values only. Following is the code I am using:

SearchQuery query = //get the query
SearchResponse hits = template.query(query, new ResultsExtractor<SearchResponse>() {
                @Override
                public SearchResponse extract(SearchResponse response) {
                    return response;
                }
            });

To debug the problem further, I wrote the code to execute the query rather than using spring data. Following is the code:

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

To my surprise, this query executed correctly and filters were applied on aggregates as well. To analyze further, I went through the code of elasticsearchtemplate and found that it uses setPostFilter method to set the filter. I then modified my code to set the filter that way:

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

When I executed above code, it showed same behavior as spring data! (i.e. filters were applied on query but not aggregates.Is this a bug of spring data es? If not, then, is there any other method which I should be using to retrieve the data the way I want?

Thanks in advance.

解决方案

This behaviour is by design in Elasticsearch.

In very simple words, input to aggregations AND post filter is the set of documents that match the query section of the request body. Hence aggregations are not applied over the filtered documents.

However, if you do want aggregations to be applied over the filtered documents, "move the filters inside the query section", that is, use filtered query. Now output of the query section will be the filtered set of documents and aggregations will apply on them as expected.

So for your requirements, use filtered query instead of post filter.

这篇关于弹出数据ElastiSearch与过滤器的聚合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-13 05:04