Put mapping operations must update metadata of all types.

Today put mapping operations only update metadata of the type that is being
modified, which is not enough since some modifications may have side-effects
on other types.

Closes #16239
This commit is contained in:
Adrien Grand 2016-01-27 14:36:09 +01:00
parent 99a7d8e41f
commit 4ab7a18738
2 changed files with 27 additions and 15 deletions

View File

@ -290,7 +290,7 @@ public class MetaDataMappingService extends AbstractComponent {
if (!MapperService.DEFAULT_MAPPING.equals(mappingType) && !PercolatorService.TYPE_NAME.equals(mappingType) && mappingType.charAt(0) == '_') { if (!MapperService.DEFAULT_MAPPING.equals(mappingType) && !PercolatorService.TYPE_NAME.equals(mappingType) && mappingType.charAt(0) == '_') {
throw new InvalidTypeNameException("Document mapping type name can't start with '_'"); throw new InvalidTypeNameException("Document mapping type name can't start with '_'");
} }
final Map<String, MappingMetaData> mappings = new HashMap<>(); MetaData.Builder builder = MetaData.builder(currentState.metaData());
for (String index : request.indices()) { for (String index : request.indices()) {
// do the actual merge here on the master, and update the mapping source // do the actual merge here on the master, and update the mapping source
IndexService indexService = indicesService.indexService(index); IndexService indexService = indicesService.indexService(index);
@ -311,7 +311,6 @@ public class MetaDataMappingService extends AbstractComponent {
// same source, no changes, ignore it // same source, no changes, ignore it
} else { } else {
// use the merged mapping source // use the merged mapping source
mappings.put(index, new MappingMetaData(mergedMapper));
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("[{}] update_mapping [{}] with source [{}]", index, mergedMapper.type(), updatedSource); logger.debug("[{}] update_mapping [{}] with source [{}]", index, mergedMapper.type(), updatedSource);
} else if (logger.isInfoEnabled()) { } else if (logger.isInfoEnabled()) {
@ -320,28 +319,24 @@ public class MetaDataMappingService extends AbstractComponent {
} }
} else { } else {
mappings.put(index, new MappingMetaData(mergedMapper));
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("[{}] create_mapping [{}] with source [{}]", index, mappingType, updatedSource); logger.debug("[{}] create_mapping [{}] with source [{}]", index, mappingType, updatedSource);
} else if (logger.isInfoEnabled()) { } else if (logger.isInfoEnabled()) {
logger.info("[{}] create_mapping [{}]", index, mappingType); logger.info("[{}] create_mapping [{}]", index, mappingType);
} }
} }
}
if (mappings.isEmpty()) { IndexMetaData indexMetaData = currentState.metaData().index(index);
// no changes, return
return currentState;
}
MetaData.Builder builder = MetaData.builder(currentState.metaData());
for (String indexName : request.indices()) {
IndexMetaData indexMetaData = currentState.metaData().index(indexName);
if (indexMetaData == null) { if (indexMetaData == null) {
throw new IndexNotFoundException(indexName); throw new IndexNotFoundException(index);
} }
MappingMetaData mappingMd = mappings.get(indexName); IndexMetaData.Builder indexMetaDataBuilder = IndexMetaData.builder(indexMetaData);
if (mappingMd != null) { // Mapping updates on a single type may have side-effects on other types so we need to
builder.put(IndexMetaData.builder(indexMetaData).putMapping(mappingMd)); // update mapping metadata on all types
for (DocumentMapper mapper : indexService.mapperService().docMappers(true)) {
indexMetaDataBuilder.putMapping(new MappingMetaData(mapper.mappingSource()));
} }
builder.put(indexMetaDataBuilder);
} }
return ClusterState.builder(currentState).metaData(builder).build(); return ClusterState.builder(currentState).metaData(builder).build();

View File

@ -35,6 +35,7 @@ import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -337,4 +338,20 @@ public class UpdateMappingIntegrationIT extends ESIntegTestCase {
} }
} }
} }
public void testUpdateMappingOnAllTypes() throws IOException {
assertAcked(prepareCreate("index").addMapping("type1", "f", "type=string").addMapping("type2", "f", "type=string"));
assertAcked(client().admin().indices().preparePutMapping("index")
.setType("type1")
.setUpdateAllTypes(true)
.setSource("f", "type=string,analyzer=default,null_value=n/a")
.get());
GetMappingsResponse mappings = client().admin().indices().prepareGetMappings("index").setTypes("type2").get();
MappingMetaData type2Mapping = mappings.getMappings().get("index").get("type2").get();
Map<String, Object> properties = (Map<String, Object>) type2Mapping.sourceAsMap().get("properties");
Map<String, Object> f = (Map<String, Object>) properties.get("f");
assertEquals("n/a", f.get("null_value"));
}
} }