Mappings: Lock down _index field

see #8143
closes #9870
This commit is contained in:
Ryan Ernst 2015-02-24 22:45:40 -08:00
parent cc2b00c443
commit 32e042f1c4
5 changed files with 51 additions and 39 deletions

View File

@ -253,6 +253,7 @@ to provide special features. They now have limited configuration options.
* `_id` configuration can no longer be changed. If you need to sort, use `_uid` instead.
* `_type` configuration can no longer be changed.
* `_index` configuration is limited to enabling the field.
=== Codecs

View File

@ -23,6 +23,7 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.IndexOptions;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.Lucene;
@ -97,7 +98,9 @@ public class IndexFieldMapper extends AbstractFieldMapper<String> implements Int
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
IndexFieldMapper.Builder builder = MapperBuilders.index();
parseField(builder, builder.name, node, parserContext);
if (parserContext.indexVersionCreated().before(Version.V_2_0_0)) {
parseField(builder, builder.name, node, parserContext);
}
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String, Object> entry = iterator.next();
@ -200,18 +203,19 @@ public class IndexFieldMapper extends AbstractFieldMapper<String> implements Int
return builder;
}
builder.startObject(CONTENT_TYPE);
if (includeDefaults || fieldType().stored() != Defaults.FIELD_TYPE.stored()) {
if (writePre2xSettings && (includeDefaults || fieldType().stored() != Defaults.FIELD_TYPE.stored())) {
builder.field("store", fieldType().stored());
}
if (includeDefaults || enabledState != Defaults.ENABLED_STATE) {
builder.field("enabled", enabledState.enabled);
}
if (customFieldDataSettings != null) {
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
} else if (includeDefaults) {
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
if (writePre2xSettings) {
if (customFieldDataSettings != null) {
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
} else if (includeDefaults) {
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
}
}
builder.endObject();
return builder;

View File

@ -19,6 +19,10 @@
package org.elasticsearch.index.mapper.index;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
@ -29,20 +33,15 @@ import org.junit.Test;
import static org.hamcrest.Matchers.*;
/**
*
*/
public class IndexTypeMapperTests extends ElasticsearchSingleNodeTest {
@Test
public void simpleIndexMapperTests() throws Exception {
public void testSimpleIndexMapper() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_index").field("enabled", true).field("store", "yes").endObject()
.startObject("_index").field("enabled", true).endObject()
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
assertThat(indexMapper.enabled(), equalTo(true));
assertThat(indexMapper.fieldType().stored(), equalTo(true));
assertThat(docMapper.mappers().indexName("_index").mapper(), instanceOf(IndexFieldMapper.class));
ParsedDocument doc = docMapper.parse("type", "1", XContentFactory.jsonBuilder()
@ -54,16 +53,14 @@ public class IndexTypeMapperTests extends ElasticsearchSingleNodeTest {
assertThat(doc.rootDoc().get("_index"), equalTo("test"));
assertThat(doc.rootDoc().get("field"), equalTo("value"));
}
@Test
public void explicitDisabledIndexMapperTests() throws Exception {
public void testExplicitDisabledIndexMapper() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_index").field("enabled", false).field("store", "yes").endObject()
.startObject("_index").field("enabled", false).endObject()
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
assertThat(indexMapper.enabled(), equalTo(false));
assertThat(indexMapper.fieldType().stored(), equalTo(true));
ParsedDocument doc = docMapper.parse("type", "1", XContentFactory.jsonBuilder()
.startObject()
@ -74,15 +71,13 @@ public class IndexTypeMapperTests extends ElasticsearchSingleNodeTest {
assertThat(doc.rootDoc().get("_index"), nullValue());
assertThat(doc.rootDoc().get("field"), equalTo("value"));
}
@Test
public void defaultDisabledIndexMapperTests() throws Exception {
public void testDefaultDisabledIndexMapper() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
assertThat(indexMapper.enabled(), equalTo(false));
assertThat(indexMapper.fieldType().stored(), equalTo(false));
ParsedDocument doc = docMapper.parse("type", "1", XContentFactory.jsonBuilder()
.startObject()
@ -93,26 +88,24 @@ public class IndexTypeMapperTests extends ElasticsearchSingleNodeTest {
assertThat(doc.rootDoc().get("_index"), nullValue());
assertThat(doc.rootDoc().get("field"), equalTo("value"));
}
@Test
public void testThatMergingFieldMappingAllowsDisabling() throws Exception {
String mappingWithIndexEnabled = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_index").field("enabled", true).field("store", "yes").endObject()
.startObject("_index").field("enabled", true).endObject()
.endObject().endObject().string();
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
DocumentMapper mapperEnabled = parser.parse(mappingWithIndexEnabled);
String mappingWithIndexDisabled = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_index").field("enabled", false).field("store", "yes").endObject()
.startObject("_index").field("enabled", false).endObject()
.endObject().endObject().string();
DocumentMapper mapperDisabled = parser.parse(mappingWithIndexDisabled);
mapperEnabled.merge(mapperDisabled, DocumentMapper.MergeFlags.mergeFlags().simulate(false));
assertThat(mapperEnabled.IndexFieldMapper().enabled(), is(false));
}
@Test
public void testThatDisablingWorksWhenMerging() throws Exception {
String enabledMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_index").field("enabled", true).endObject()
@ -128,4 +121,26 @@ public class IndexTypeMapperTests extends ElasticsearchSingleNodeTest {
enabledMapper.merge(disabledMapper, DocumentMapper.MergeFlags.mergeFlags().simulate(false));
assertThat(enabledMapper.indexMapper().enabled(), is(false));
}
public void testCustomSettingsBackcompat() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_index")
.field("enabled", true)
.field("store", "yes").endObject()
.endObject().endObject().string();
Settings indexSettings = ImmutableSettings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
DocumentMapper docMapper = createIndex("test", indexSettings).mapperService().documentMapperParser().parse(mapping);
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
assertThat(indexMapper.enabled(), equalTo(true));
assertThat(indexMapper.fieldType().stored(), equalTo(true));
ParsedDocument doc = docMapper.parse("type", "1", XContentFactory.jsonBuilder()
.startObject()
.field("field", "value")
.endObject()
.bytes());
assertThat(doc.rootDoc().get("_index"), equalTo("test"));
assertThat(doc.rootDoc().get("field"), equalTo("value"));
}
}

View File

@ -120,22 +120,14 @@ public class UpdateMappingTests extends ElasticsearchSingleNodeTest {
.startObject("type")
.startObject("_index")
.field("enabled", enabled)
.field("store", true)
.startObject("fielddata")
.field("format", "fst")
.endObject()
.endObject()
.endObject()
.endObject();
DocumentMapper documentMapper = indexService.mapperService().parse("type", new CompressedString(indexMapping.string()), true);
assertThat(documentMapper.indexMapper().enabled(), equalTo(enabled));
assertTrue(documentMapper.indexMapper().fieldType().stored());
assertThat(documentMapper.indexMapper().fieldDataType().getFormat(null), equalTo("fst"));
documentMapper.refreshSource();
documentMapper = indexService.mapperService().parse("type", new CompressedString(documentMapper.mappingSource().string()), true);
assertThat(documentMapper.indexMapper().enabled(), equalTo(enabled));
assertTrue(documentMapper.indexMapper().fieldType().stored());
assertThat(documentMapper.indexMapper().fieldDataType().getFormat(null), equalTo("fst"));
}
@Test

View File

@ -1 +1 @@
{"type":{"_timestamp":{"enabled":false,"doc_values":true,"fielddata":{"format":"doc_values"}},"_index":{"store":true,"enabled":false,"fielddata":{"format":"fst"}},"_size":{"enabled":false},"properties":{}}}
{"type":{"_timestamp":{"enabled":false,"doc_values":true,"fielddata":{"format":"doc_values"}},"_index":{"enabled":false},"_size":{"enabled":false},"properties":{}}}