Skip to content

Commit ac59026

Browse files
[7.x][ML] Improve error upon DF analytics mappings conflict (#56700) (#56776)
Adds the conflicting types and an example of an index which specifies them in order to make it easier for the user to understand the conflict. Backport of #56700
1 parent 2921747 commit ac59026

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/MappingsMerger.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.HashMap;
2323
import java.util.Iterator;
2424
import java.util.Map;
25+
import java.util.Objects;
26+
import java.util.stream.Collectors;
2527

2628
import static org.elasticsearch.xpack.core.ClientHelper.ML_ORIGIN;
2729

@@ -50,7 +52,7 @@ static ImmutableOpenMap<String, MappingMetadata> mergeMappings(DataFrameAnalytic
5052
ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetadata>> indexToMappings = getMappingsResponse.getMappings();
5153

5254
String type = null;
53-
Map<String, Object> mergedMappings = new HashMap<>();
55+
Map<String, IndexAndMapping> mergedMappings = new HashMap<>();
5456

5557
Iterator<ObjectObjectCursor<String, ImmutableOpenMap<String, MappingMetadata>>> iterator = indexToMappings.iterator();
5658
while (iterator.hasNext()) {
@@ -76,20 +78,25 @@ static ImmutableOpenMap<String, MappingMetadata> mergeMappings(DataFrameAnalytic
7678
String field = fieldMapping.getKey();
7779
if (source.isFieldExcluded(field) == false) {
7880
if (mergedMappings.containsKey(field)) {
79-
if (mergedMappings.get(field).equals(fieldMapping.getValue()) == false) {
81+
IndexAndMapping existingIndexAndMapping = mergedMappings.get(field);
82+
if (existingIndexAndMapping.mapping.equals(fieldMapping.getValue()) == false) {
8083
throw ExceptionsHelper.badRequestException(
81-
"cannot merge mappings because of differences for field [{}]", field);
84+
"cannot merge mappings because of differences for field [{}]; mapped as [{}] in index [{}]; " +
85+
"mapped as [{}] in index [{}]", field, fieldMapping.getValue(), indexMappings.key,
86+
existingIndexAndMapping.mapping, existingIndexAndMapping.index);
87+
8288
}
8389
} else {
84-
mergedMappings.put(field, fieldMapping.getValue());
90+
mergedMappings.put(field, new IndexAndMapping(indexMappings.key, fieldMapping.getValue()));
8591
}
8692
}
8793
}
8894
}
8995
}
9096
}
9197

92-
MappingMetadata mappingMetadata = createMappingMetadata(type, mergedMappings);
98+
MappingMetadata mappingMetadata = createMappingMetadata(type,
99+
mergedMappings.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().mapping)));
93100
ImmutableOpenMap.Builder<String, MappingMetadata> result = ImmutableOpenMap.builder();
94101
result.put(type, mappingMetadata);
95102
return result.build();
@@ -102,4 +109,14 @@ private static MappingMetadata createMappingMetadata(String type, Map<String, Ob
102109
throw ExceptionsHelper.serverError("Failed to parse mappings: " + mappings);
103110
}
104111
}
112+
113+
private static class IndexAndMapping {
114+
private final String index;
115+
private final Object mapping;
116+
117+
private IndexAndMapping(String index, Object mapping) {
118+
this.index = Objects.requireNonNull(index);
119+
this.mapping = Objects.requireNonNull(mapping);
120+
}
121+
}
105122
}

x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/dataframe/MappingsMergerTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ public void testMergeMappings_GivenFieldWithDifferentMapping() throws IOExceptio
108108
ElasticsearchStatusException e = expectThrows(ElasticsearchStatusException.class,
109109
() -> MappingsMerger.mergeMappings(newSource(), getMappingsResponse));
110110
assertThat(e.status(), equalTo(RestStatus.BAD_REQUEST));
111-
assertThat(e.getMessage(), equalTo("cannot merge mappings because of differences for field [field_1]"));
111+
assertThat(e.getMessage(), containsString("cannot merge mappings because of differences for field [field_1]; "));
112+
assertThat(e.getMessage(), containsString("mapped as [different_field_1_mappings] in index [index_2]"));
113+
assertThat(e.getMessage(), containsString("mapped as [field_1_mappings] in index [index_1]"));
112114
}
113115

114116
public void testMergeMappings_GivenIndicesWithDifferentMappingsButNoConflicts() throws IOException {

0 commit comments

Comments
 (0)