### Elasticsearch Version

many

### Installed Plugins

none

### Java Version

_bundled_

### OS Version

all

### Problem Description

The `filter_by_filter` optimization should kick in when it makes aggs faster. We have a switch to turn it off, but we advise folks not to because it usually does a good job. Well, we've found a case where the heuristics do a bad job of picking the implementation - specifically I've seen a case when the `_doc_count` field exists and we're slower. I'm not really sure if this is universal, but it could be. I'm trying to figure out if this is an all the time thing or a sometimes thing.

### Steps to Reproduce

index docs with `_doc_count`. run a terms agg on a field with a cardinality in the ball park of 500.

### Logs (if relevant)

_No response_
server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterByFilterAggregator.java
* sub-aggregators between each filter as though they were hitting
     * a fresh segment.
     * <p>
     * It's <strong>very</strong> tempting to try and collect the
     * filters into blocks of matches and then reply the whole block
     * into ascending order without the resetting. That'd probably
     * work better if the disk was very, very slow and we didn't have
     * any kind of disk caching. But with disk caching its about twice
     * as fast to collect each filter one by one like this. And it uses
     * less memory because there isn't a need to buffer a block of matches.
     * And its a hell of a lot less code.
     */
    private void collectSubs(LeafReaderContext ctx, Bits live, LeafBucketCollector sub) throws IOException {
        class MatchCollector implements LeafCollector {
            LeafBucketCollector subCollector = sub;
            int filterOrd;
            @Override
            public void collect(int docId) throws IOException {
                collectBucket(subCollector, docId, filterOrd);
            }
            @Override
            public void setScorer(Scorable scorer) throws IOException {}
        }
        MatchCollector collector = new MatchCollector();
        filters().get(0).collect(ctx, collector, live);
        for (int filterOrd = 1; filterOrd < filters().size(); filterOrd++) {
            collector.subCollector = collectableSubAggregators.getLeafCollector(ctx);
            collector.filterOrd = filterOrd;
            filters().get(filterOrd).collect(ctx, collector, live);
        }