### Description

We have had this longstanding issue that running a top-level `filter` aggregation is often (not always, e.g. not if you need the total hit count too) a performance bug, as Elasticsearch would iterate over docs that match the `query` and would then check each of these docs against the filter of the `filter` aggregation. It's usually a better idea to put the filter directly into the query, where it can be used to drive iteration if appropriate.

We could do this automatically by implementing the `LeafCollector#competitiveIterator` API that was introduced for dynamic pruning, in order to automatically start intersecting the query with the filter of the `filter` aggregator once enough hits have been counted.
server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/QueryToFilterAdapter.java
builder.add(extraQuery, BooleanClause.Occur.FILTER);
        Query rewrittenUnion = searcher().rewrite(new ConstantScoreQuery(builder.build()));
        if (rewrittenUnion instanceof ConstantScoreQuery) {
            rewrittenUnion = ((ConstantScoreQuery) rewrittenUnion).getQuery();
        }
        
        final boolean inefficientUnion = rewrittenUnion instanceof BooleanQuery;
        return new QueryToFilterAdapter(searcher(), key(), rewrittenUnion) {
            public boolean isInefficientUnion() {
                return inefficientUnion;
            }
        };
    }
    private static Query unwrap(Query query) {
        while (true) {
            if (query instanceof ConstantScoreQuery) {
                query = ((ConstantScoreQuery) query).getQuery();
                continue;
            }
            if (query instanceof IndexSortSortedNumericDocValuesRangeQuery) {
                query = ((IndexSortSortedNumericDocValuesRangeQuery) query).getFallbackQuery();
                continue;
            }
            if (query instanceof IndexOrDocValuesQuery) {
                query = ((IndexOrDocValuesQuery) query).getIndexQuery();
                continue;
            }
            return query;
        }
    }