From 93f590671cad3b89f45deefcd3c6c6ab7dca6201 Mon Sep 17 00:00:00 2001 From: Augment Agent Date: Sat, 28 Feb 2026 01:03:54 +0000 Subject: [PATCH] Fix effective_mapping field to remove _doc wrapper in data stream API responses The effective_mapping field in the get data stream API response was incorrectly including a _doc wrapper at the top level, which doesn't match the specification. Changes: - Modified DataStream.getEffectiveMappings() to strip the _doc wrapper from the merged mapping before returning it - Updated YAML REST tests to expect the correct format without the _doc wrapper - All unit tests and YAML REST tests pass with the updated format The fix ensures that effective_mappings now returns: {"properties": {...}} instead of: {"_doc": {"properties": {...}}} This aligns the response structure with the API specification and unit test expectations. Fixes issue reported in: https://augment-wic8570.slack.com/archives/C0AG2MXKEQJ/p1772239116341799 --- .../data_stream/250_data_stream_mappings.yml | 28 +++++++++---------- .../cluster/metadata/DataStream.java | 11 +++++++- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/250_data_stream_mappings.yml b/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/250_data_stream_mappings.yml index c0fef3e6bae07..5dc465d05a80a 100644 --- a/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/250_data_stream_mappings.yml +++ b/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/250_data_stream_mappings.yml @@ -34,7 +34,7 @@ setup: name: my-data-stream-1 - match: { data_streams.0.name: my-data-stream-1 } - match: { data_streams.0.mappings: {} } - - length: { data_streams.0.effective_mappings._doc.properties: 2 } + - length: { data_streams.0.effective_mappings.properties: 2 } - do: indices.get_data_stream: @@ -56,7 +56,7 @@ setup: - match: { data_streams.0.name: my-data-stream-1 } - match: { data_streams.0.applied_to_data_stream: true } - match: { data_streams.0.mappings.properties.name.type: "keyword" } - - match: { data_streams.0.effective_mappings._doc.properties.name.type: "keyword" } + - match: { data_streams.0.effective_mappings.properties.name.type: "keyword" } - do: indices.rollover: @@ -71,9 +71,9 @@ setup: indices.get_data_stream_mappings: name: my-data-stream-1 - match: { data_streams.0.name: my-data-stream-1 } - - length: { data_streams.0.effective_mappings._doc.properties: 3 } + - length: { data_streams.0.effective_mappings.properties: 3 } - match: { data_streams.0.mappings.properties.name.type: "keyword" } - - match: { data_streams.0.effective_mappings._doc.properties.name.type: "keyword" } + - match: { data_streams.0.effective_mappings.properties.name.type: "keyword" } - do: indices.get_data_stream: @@ -149,9 +149,9 @@ setup: - match: { data_streams.0.mappings.properties.field1.type: "text" } - match: { data_streams.0.mappings.properties.field2: null } - match: { data_streams.0.mappings.properties.field3.type: "text" } - - match: { data_streams.0.effective_mappings._doc.properties.field1.type: "text" } - - match: { data_streams.0.effective_mappings._doc.properties.field2.type: "keyword" } - - match: { data_streams.0.effective_mappings._doc.properties.field3.type: "text" } + - match: { data_streams.0.effective_mappings.properties.field1.type: "text" } + - match: { data_streams.0.effective_mappings.properties.field2.type: "keyword" } + - match: { data_streams.0.effective_mappings.properties.field3.type: "text" } - do: cluster.put_component_template: @@ -180,10 +180,10 @@ setup: indices.get_data_stream_mappings: name: my-component-only-data-stream-1 - match: { data_streams.0.name: my-component-only-data-stream-1 } - - length: { data_streams.0.effective_mappings._doc.properties: 5 } + - length: { data_streams.0.effective_mappings.properties: 5 } - match: { data_streams.0.mappings.properties.field1.type: "text" } - - match: { data_streams.0.effective_mappings._doc.properties.field3.type: "text" } - - match: { data_streams.0.effective_mappings._doc.properties.field4.type: "keyword" } + - match: { data_streams.0.effective_mappings.properties.field3.type: "text" } + - match: { data_streams.0.effective_mappings.properties.field4.type: "keyword" } - do: indices.get_data_stream: @@ -212,7 +212,7 @@ setup: - match: { data_streams.0.name: my-component-only-data-stream-1 } - match: { data_streams.0.applied_to_data_stream: true } - match: { data_streams.0.mappings null } - - match: { data_streams.0.effective_mappings._doc.properties.field1.type: "keyword" } - - match: { data_streams.0.effective_mappings._doc.properties.field2.type: "keyword" } - - match: { data_streams.0.effective_mappings._doc.properties.field3: null } - - match: { data_streams.0.effective_mappings._doc.properties.field4.type: "keyword" } + - match: { data_streams.0.effective_mappings.properties.field1.type: "keyword" } + - match: { data_streams.0.effective_mappings.properties.field2.type: "keyword" } + - match: { data_streams.0.effective_mappings.properties.field3: null } + - match: { data_streams.0.effective_mappings.properties.field4.type: "keyword" } diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java b/server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java index fddcc838e3a11..0a7b328f67823 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java @@ -499,7 +499,7 @@ public static CompressedXContent getEffectiveMappings( xContentRegistry, writeIndex.getName() ); - return indicesService.withTempIndexService(projectMetadata.index(writeIndex), indexService -> { + CompressedXContent mergedMapping = indicesService.withTempIndexService(projectMetadata.index(writeIndex), indexService -> { MapperService mapperService = indexService.mapperService(); DocumentMapper documentMapper = mapperService.merge( MapperService.SINGLE_MAPPING_NAME, @@ -508,6 +508,15 @@ public static CompressedXContent getEffectiveMappings( ); return documentMapper.mappingSource(); }); + + // Strip the _doc wrapper from the merged mapping to match the API specification + Map mergedMappingMap = XContentHelper.convertToMap(mergedMapping.uncompressed(), true, XContentType.JSON).v2(); + if (mergedMappingMap.containsKey(MapperService.SINGLE_MAPPING_NAME)) { + mergedMapping = ComposableIndexTemplate.convertMappingMapToXContent( + (Map) mergedMappingMap.get(MapperService.SINGLE_MAPPING_NAME) + ); + } + return mergedMapping; } private ComposableIndexTemplate getMatchingIndexTemplate(ProjectMetadata projectMetadata) {