1

いくつかの条件でフィルタリングされた値に対して集計を実行しようとしています。私は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のバグですか?そうでない場合、希望する方法でデータを取得するために使用する必要がある他の方法はありますか?

前もって感謝します。

4

1 に答える 1

8

この動作は、Elasticsearch の設計によるものです。

query非常に簡単に言えば、集計 AND ポスト フィルターへの入力は、要求本文のセクションに一致するドキュメントのセットです。したがって、フィルタリングされたドキュメントに対して集計は適用されません。

ただし、フィルター処理されたドキュメントに集計を適用する場合は、「フィルターをqueryセクション内に移動」します。つまり、フィルター処理されたクエリを使用します。これで、セクションの出力はqueryフィルター処理された一連のドキュメントになり、期待どおりに集計が適用されます。

そのため、要件に合わせて、投稿フィルターの代わりにフィルターされたクエリを使用してください。

于 2015-02-01T14:20:03.097 に答える