### Elasticsearch Version

8.11.1

### Installed Plugins

_No response_

### Java Version

_bundled_

### OS Version

N/A (Elastic Cloud)

### Problem Description

`_cluster/stats` returns a NullPointerException when there is an index with a dense_vector without dims, which is allowed as reported in the [documentation of the dense_vector type](https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html). 
This endpoint is also used by Elastic-Agent/Metricbeat to gather cluster statistics and this bug can cause them not to work.

### Steps to Reproduce

Create a new index with the following mapping:
```
PUT breaking-cluster-stats
{
  "mappings": {
    "properties": {
      "foo": {
        "type": "dense_vector"
      }
    }
  }
}
```

Execute `_cluster/stats`. It will return:

```
{
  "error": {
    "root_cause": [
      {
        "type": "null_pointer_exception",
        "reason": "Cannot invoke \"java.lang.Integer.intValue()\" because the return value of \"java.util.Map.get(Object)\" is null"
      }
    ],
    "type": "null_pointer_exception",
    "reason": "Cannot invoke \"java.lang.Integer.intValue()\" because the return value of \"java.util.Map.get(Object)\" is null"
  },
  "status": 500
}
```

### Workaround

Create mapping with dims property or index a vector with the number of dimensions needed, e.g.: 
```
PUT breaking-cluster-stats/_doc/1 
{
  "foo": [1,1,1,1,...,1]
}
```

### Logs (if relevant)

Stack Trace:
> java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null at org.elasticsearch.action.admin.cluster.stats.MappingStats.lambda$of$0(MappingStats.java:91) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:38) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:39) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:39) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:39) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:39) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:39) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:39) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingVisitor.visitMapping(MappingVisitor.java:19) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.MappingStats.of(MappingStats.java:73) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction$MetadataStatsCache.lambda$refresh$0(TransportClusterStatsAction.java:293) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.ActionListener.completeWith(ActionListener.java:299) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction$MetadataStatsCache.refresh(TransportClusterStatsAction.java:293) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction$MetadataStatsCache.refresh(TransportClusterStatsAction.java:278) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.common.util.CancellableSingleObjectCache$CachedItem.startRefresh(CancellableSingleObjectCache.java:289) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.common.util.CancellableSingleObjectCache.get(CancellableSingleObjectCache.java:167) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction.newResponseAsync(TransportClusterStatsAction.java:132) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction.newResponseAsync(TransportClusterStatsAction.java:58) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.support.nodes.TransportNodesAction$1.lambda$onCompletion$1(TransportNodesAction.java:142) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.support.nodes.TransportNodesAction.lambda$doExecute$0(TransportNodesAction.java:152) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.ActionListenerImplementations$ResponseWrappingActionListener.onResponse(ActionListenerImplementations.java:236) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.action.support.ThreadedActionListener$1.doRun(ThreadedActionListener.java:50) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:983) ~[elasticsearch-8.11.1.jar:?] at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:26) ~[elasticsearch-8.11.1.jar:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.lang.Thread.run(Thread.java:1583) ~[?:?]
server/src/main/java/org/elasticsearch/action/admin/cluster/stats/MappingStats.java
builder.endArray();
        builder.startArray("runtime_field_types");
        for (RuntimeFieldStats st : runtimeFieldStats) {
            st.toXContent(builder, params);
        }
        builder.endArray();
        builder.endObject();
        return builder;
    }
    @Override
    public String toString() {
        return Strings.toString(this, true, true);
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MappingStats that = (MappingStats) o;
        return Objects.equals(totalFieldCount, that.totalFieldCount)
            && Objects.equals(totalDeduplicatedFieldCount, that.totalDeduplicatedFieldCount)
            && Objects.equals(totalMappingSizeBytes, that.totalMappingSizeBytes)
            && fieldTypeStats.equals(that.fieldTypeStats)
            && runtimeFieldStats.equals(that.runtimeFieldStats);
    }
    @Override
    public int hashCode() {
        return Objects.hash(totalFieldCount, totalDeduplicatedFieldCount, totalMappingSizeBytes, fieldTypeStats, runtimeFieldStats);
    }
}