### Description

`TransportFieldCapabilitiesAction` (used for the the `_field_caps` endpoint) has got a nested loop in `merge` method when unmapped fields are included (https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/fieldcaps/TransportFieldCapabilitiesAction.java#L245). This loops over indices -> fields -> indices, which could cause an exponential blowup in objects used when there's a large number of indices and unmapped fields.

We could be more efficient in creating & sharing IndexCap objects in these situations.
server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilities.java
nonSearchableIndices != null ? nonSearchableIndices.toArray(new String[0]) : null,
            nonAggregatableIndices != null ? nonAggregatableIndices.toArray(new String[0]) : null,
            nonDimensionIndices != null ? nonDimensionIndices.toArray(new String[0]) : null,
            metricConflictsIndices != null ? metricConflictsIndices.toArray(new String[0]) : null,
            meta != null ? meta : Collections.emptyMap()
        );
    }
    FieldCapabilities(StreamInput in) throws IOException {
        this.name = in.readString();
        this.type = in.readString();
        this.isMetadataField = in.readBoolean();
        this.isSearchable = in.readBoolean();
        this.isAggregatable = in.readBoolean();
        if (in.getVersion().onOrAfter(Version.V_8_0_0)) {
            this.isDimension = in.readBoolean();
            this.metricType = in.readOptionalEnum(TimeSeriesParams.MetricType.class);
        } else {
            this.isDimension = false;
            this.metricType = null;
        }
        this.indices = in.readOptionalStringArray();
        this.nonSearchableIndices = in.readOptionalStringArray();
        this.nonAggregatableIndices = in.readOptionalStringArray();
        if (in.getVersion().onOrAfter(Version.V_8_0_0)) {
            this.nonDimensionIndices = in.readOptionalStringArray();
            this.metricConflictsIndices = in.readOptionalStringArray();
        } else {
            this.nonDimensionIndices = null;
            this.metricConflictsIndices = null;
        }