88
99package org .elasticsearch .action .admin .cluster .stats ;
1010
11+ import org .elasticsearch .Version ;
1112import org .elasticsearch .cluster .metadata .IndexMetadata ;
1213import org .elasticsearch .cluster .metadata .MappingMetadata ;
1314import org .elasticsearch .cluster .metadata .Metadata ;
1415import org .elasticsearch .common .Strings ;
1516import org .elasticsearch .common .io .stream .StreamInput ;
1617import org .elasticsearch .common .io .stream .StreamOutput ;
1718import org .elasticsearch .common .io .stream .Writeable ;
19+ import org .elasticsearch .common .unit .ByteSizeValue ;
20+ import org .elasticsearch .core .Nullable ;
1821import org .elasticsearch .xcontent .ToXContentFragment ;
1922import org .elasticsearch .xcontent .XContentBuilder ;
2023
2932import java .util .List ;
3033import java .util .Map ;
3134import java .util .Objects ;
35+ import java .util .OptionalLong ;
3236import java .util .Set ;
37+ import java .util .concurrent .atomic .AtomicLong ;
3338import java .util .regex .Matcher ;
3439import java .util .regex .Pattern ;
3540
@@ -57,6 +62,8 @@ public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
5762 }
5863 AnalysisStats .countMapping (mappingCounts , indexMetadata );
5964 }
65+ final AtomicLong totalFieldCount = new AtomicLong ();
66+ final AtomicLong totalDeduplicatedFieldCount = new AtomicLong ();
6067 for (Map .Entry <MappingMetadata , Integer > mappingAndCount : mappingCounts .entrySet ()) {
6168 ensureNotCancelled .run ();
6269 Set <String > indexFieldTypes = new HashSet <>();
@@ -73,6 +80,8 @@ public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
7380 type = "object" ;
7481 }
7582 if (type != null ) {
83+ totalDeduplicatedFieldCount .incrementAndGet ();
84+ totalFieldCount .addAndGet (count );
7685 FieldStats stats ;
7786 if (type .equals ("dense_vector" )) {
7887 stats = fieldTypes .computeIfAbsent (type , DenseVectorFieldStats ::new );
@@ -134,7 +143,17 @@ public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
134143 }
135144 });
136145 }
137- return new MappingStats (fieldTypes .values (), runtimeFieldTypes .values ());
146+ long totalMappingSizeBytes = 0L ;
147+ for (MappingMetadata mappingMetadata : metadata .getMappingsByHash ().values ()) {
148+ totalMappingSizeBytes += mappingMetadata .source ().compressed ().length ;
149+ }
150+ return new MappingStats (
151+ totalFieldCount .get (),
152+ totalDeduplicatedFieldCount .get (),
153+ totalMappingSizeBytes ,
154+ fieldTypes .values (),
155+ runtimeFieldTypes .values ()
156+ );
138157 }
139158
140159 private static void updateScriptParams (Object scriptSourceObject , FieldScriptStats scriptStats , int multiplier ) {
@@ -157,10 +176,28 @@ private static int countOccurrences(String script, Pattern pattern) {
157176 return occurrences ;
158177 }
159178
179+ @ Nullable // for BwC
180+ private final Long totalFieldCount ;
181+
182+ @ Nullable // for BwC
183+ private final Long totalDeduplicatedFieldCount ;
184+
185+ @ Nullable // for BwC
186+ private final Long totalMappingSizeBytes ;
187+
160188 private final List <FieldStats > fieldTypeStats ;
161189 private final List <RuntimeFieldStats > runtimeFieldStats ;
162190
163- MappingStats (Collection <FieldStats > fieldTypeStats , Collection <RuntimeFieldStats > runtimeFieldStats ) {
191+ MappingStats (
192+ long totalFieldCount ,
193+ long totalDeduplicatedFieldCount ,
194+ long totalMappingSizeBytes ,
195+ Collection <FieldStats > fieldTypeStats ,
196+ Collection <RuntimeFieldStats > runtimeFieldStats
197+ ) {
198+ this .totalFieldCount = totalFieldCount ;
199+ this .totalDeduplicatedFieldCount = totalDeduplicatedFieldCount ;
200+ this .totalMappingSizeBytes = totalMappingSizeBytes ;
164201 List <FieldStats > stats = new ArrayList <>(fieldTypeStats );
165202 stats .sort (Comparator .comparing (IndexFeatureStats ::getName ));
166203 this .fieldTypeStats = Collections .unmodifiableList (stats );
@@ -170,16 +207,57 @@ private static int countOccurrences(String script, Pattern pattern) {
170207 }
171208
172209 MappingStats (StreamInput in ) throws IOException {
210+ if (in .getVersion ().onOrAfter (Version .V_8_4_0 )) {
211+ totalFieldCount = in .readOptionalVLong ();
212+ totalDeduplicatedFieldCount = in .readOptionalVLong ();
213+ totalMappingSizeBytes = in .readOptionalVLong ();
214+ } else {
215+ totalFieldCount = null ;
216+ totalDeduplicatedFieldCount = null ;
217+ totalMappingSizeBytes = null ;
218+ }
173219 fieldTypeStats = Collections .unmodifiableList (in .readList (FieldStats ::new ));
174220 runtimeFieldStats = Collections .unmodifiableList (in .readList (RuntimeFieldStats ::new ));
175221 }
176222
177223 @ Override
178224 public void writeTo (StreamOutput out ) throws IOException {
225+ if (out .getVersion ().onOrAfter (Version .V_8_4_0 )) {
226+ out .writeOptionalVLong (totalFieldCount );
227+ out .writeOptionalVLong (totalDeduplicatedFieldCount );
228+ out .writeOptionalVLong (totalMappingSizeBytes );
229+ } // else just omit these stats, they're not computed on older nodes anyway
179230 out .writeCollection (fieldTypeStats );
180231 out .writeCollection (runtimeFieldStats );
181232 }
182233
234+ private static OptionalLong ofNullable (Long l ) {
235+ return l == null ? OptionalLong .empty () : OptionalLong .of (l );
236+ }
237+
238+ /**
239+ * @return the total number of fields (in non-system indices), or {@link OptionalLong#empty()} if omitted (due to BwC)
240+ */
241+ public OptionalLong getTotalFieldCount () {
242+ return ofNullable (totalFieldCount );
243+ }
244+
245+ /**
246+ * @return the total number of fields (in non-system indices) accounting for deduplication, or {@link OptionalLong#empty()} if omitted
247+ * (due to BwC)
248+ */
249+ public OptionalLong getTotalDeduplicatedFieldCount () {
250+ return ofNullable (totalDeduplicatedFieldCount );
251+ }
252+
253+ /**
254+ * @return the total size of all mappings (including those for system indices) accounting for deduplication and compression, or {@link
255+ * OptionalLong#empty()} if omitted (due to BwC).
256+ */
257+ public OptionalLong getTotalMappingSizeBytes () {
258+ return ofNullable (totalMappingSizeBytes );
259+ }
260+
183261 /**
184262 * Return stats about field types.
185263 */
@@ -197,6 +275,19 @@ public List<RuntimeFieldStats> getRuntimeFieldStats() {
197275 @ Override
198276 public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
199277 builder .startObject ("mappings" );
278+ if (totalFieldCount != null ) {
279+ builder .field ("total_field_count" , totalFieldCount );
280+ }
281+ if (totalDeduplicatedFieldCount != null ) {
282+ builder .field ("total_deduplicated_field_count" , totalDeduplicatedFieldCount );
283+ }
284+ if (totalMappingSizeBytes != null ) {
285+ builder .humanReadableField (
286+ "total_deduplicated_mapping_size_in_bytes" ,
287+ "total_deduplicated_mapping_size" ,
288+ ByteSizeValue .ofBytes (totalMappingSizeBytes )
289+ );
290+ }
200291 builder .startArray ("field_types" );
201292 for (IndexFeatureStats st : fieldTypeStats ) {
202293 st .toXContent (builder , params );
@@ -218,15 +309,18 @@ public String toString() {
218309
219310 @ Override
220311 public boolean equals (Object o ) {
221- if (o instanceof MappingStats == false ) {
222- return false ;
223- }
312+ if (this == o ) return true ;
313+ if (o == null || getClass () != o .getClass ()) return false ;
224314 MappingStats that = (MappingStats ) o ;
225- return fieldTypeStats .equals (that .fieldTypeStats ) && runtimeFieldStats .equals (that .runtimeFieldStats );
315+ return Objects .equals (totalFieldCount , that .totalFieldCount )
316+ && Objects .equals (totalDeduplicatedFieldCount , that .totalDeduplicatedFieldCount )
317+ && Objects .equals (totalMappingSizeBytes , that .totalMappingSizeBytes )
318+ && fieldTypeStats .equals (that .fieldTypeStats )
319+ && runtimeFieldStats .equals (that .runtimeFieldStats );
226320 }
227321
228322 @ Override
229323 public int hashCode () {
230- return Objects .hash (fieldTypeStats , runtimeFieldStats );
324+ return Objects .hash (totalFieldCount , totalDeduplicatedFieldCount , totalMappingSizeBytes , fieldTypeStats , runtimeFieldStats );
231325 }
232326}
0 commit comments