いくつかの条件でフィルタリングされた値に対して集計を実行しようとしています。私は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
メソッドを使用してフィルターを設定していることがわかりました。次に、コードを変更してフィルターをそのように設定しました。
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 Data esのバグですか?そうでない場合、希望する方法でデータを取得するために使用する必要がある他の方法はありますか?
前もって感謝します。