Merge pull request #15156 from jpountz/fix/default_type

Don't treat _default_ as a regular type.
This commit is contained in:
Adrien Grand 2015-12-01 18:14:53 +01:00
commit b2fb3a802c
6 changed files with 111 additions and 21 deletions

View File

@ -351,7 +351,7 @@ public class DocumentMapper implements ToXContent {
this.fieldMappers = this.fieldMappers.copyAndAllAll(fieldMappers); this.fieldMappers = this.fieldMappers.copyAndAllAll(fieldMappers);
// finally update for the entire index // finally update for the entire index
mapperService.addMappers(objectMappers, fieldMappers); mapperService.addMappers(type, objectMappers, fieldMappers);
} }
public MergeResult merge(Mapping mapping, boolean simulate, boolean updateAllTypes) { public MergeResult merge(Mapping mapping, boolean simulate, boolean updateAllTypes) {

View File

@ -79,6 +79,10 @@ class DocumentParser implements Closeable {
} }
private ParsedDocument innerParseDocument(SourceToParse source) throws MapperParsingException { private ParsedDocument innerParseDocument(SourceToParse source) throws MapperParsingException {
if (docMapper.type().equals(MapperService.DEFAULT_MAPPING)) {
throw new IllegalArgumentException("It is forbidden to index into the default mapping [" + MapperService.DEFAULT_MAPPING + "]");
}
ParseContext.InternalParseContext context = cache.get(); ParseContext.InternalParseContext context = cache.get();
final Mapping mapping = docMapper.mapping(); final Mapping mapping = docMapper.mapping();

View File

@ -27,6 +27,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
/** /**
@ -56,7 +57,11 @@ class FieldTypeLookup implements Iterable<MappedFieldType> {
* from the provided fields. If a field already exists, the field type will be updated * from the provided fields. If a field already exists, the field type will be updated
* to use the new mappers field type. * to use the new mappers field type.
*/ */
public FieldTypeLookup copyAndAddAll(Collection<FieldMapper> newFieldMappers) { public FieldTypeLookup copyAndAddAll(String type, Collection<FieldMapper> newFieldMappers) {
Objects.requireNonNull(type, "type must not be null");
if (MapperService.DEFAULT_MAPPING.equals(type)) {
throw new IllegalArgumentException("Default mappings should not be added to the lookup");
}
CopyOnWriteHashMap<String, MappedFieldTypeReference> fullName = this.fullNameToFieldType; CopyOnWriteHashMap<String, MappedFieldTypeReference> fullName = this.fullNameToFieldType;
CopyOnWriteHashMap<String, MappedFieldTypeReference> indexName = this.indexNameToFieldType; CopyOnWriteHashMap<String, MappedFieldTypeReference> indexName = this.indexNameToFieldType;

View File

@ -267,7 +267,7 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
} }
MapperUtils.collect(mapper.mapping().root, newObjectMappers, newFieldMappers); MapperUtils.collect(mapper.mapping().root, newObjectMappers, newFieldMappers);
checkNewMappersCompatibility(newObjectMappers, newFieldMappers, updateAllTypes); checkNewMappersCompatibility(newObjectMappers, newFieldMappers, updateAllTypes);
addMappers(newObjectMappers, newFieldMappers); addMappers(mapper.type(), newObjectMappers, newFieldMappers);
for (DocumentTypeListener typeListener : typeListeners) { for (DocumentTypeListener typeListener : typeListeners) {
typeListener.beforeCreate(mapper); typeListener.beforeCreate(mapper);
@ -318,7 +318,7 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
fieldTypes.checkCompatibility(newFieldMappers, updateAllTypes); fieldTypes.checkCompatibility(newFieldMappers, updateAllTypes);
} }
protected void addMappers(Collection<ObjectMapper> objectMappers, Collection<FieldMapper> fieldMappers) { protected void addMappers(String type, Collection<ObjectMapper> objectMappers, Collection<FieldMapper> fieldMappers) {
assert mappingLock.isWriteLockedByCurrentThread(); assert mappingLock.isWriteLockedByCurrentThread();
ImmutableOpenMap.Builder<String, ObjectMapper> fullPathObjectMappers = ImmutableOpenMap.builder(this.fullPathObjectMappers); ImmutableOpenMap.Builder<String, ObjectMapper> fullPathObjectMappers = ImmutableOpenMap.builder(this.fullPathObjectMappers);
for (ObjectMapper objectMapper : objectMappers) { for (ObjectMapper objectMapper : objectMappers) {
@ -328,7 +328,7 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
} }
} }
this.fullPathObjectMappers = fullPathObjectMappers.build(); this.fullPathObjectMappers = fullPathObjectMappers.build();
this.fieldTypes = this.fieldTypes.copyAndAddAll(fieldMappers); this.fieldTypes = this.fieldTypes.copyAndAddAll(type, fieldMappers);
} }
public DocumentMapper parse(String mappingType, CompressedXContent mappingSource, boolean applyDefault) throws MapperParsingException { public DocumentMapper parse(String mappingType, CompressedXContent mappingSource, boolean applyDefault) throws MapperParsingException {
@ -345,10 +345,21 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
return mappers.containsKey(mappingType); return mappers.containsKey(mappingType);
} }
/**
* Return the set of concrete types that have a mapping.
* NOTE: this does not return the default mapping.
*/
public Collection<String> types() { public Collection<String> types() {
return mappers.keySet(); final Set<String> types = new HashSet<>(mappers.keySet());
types.remove(DEFAULT_MAPPING);
return Collections.unmodifiableSet(types);
} }
/**
* Return the {@link DocumentMapper} for the given type. By using the special
* {@value #DEFAULT_MAPPING} type, you can get a {@link DocumentMapper} for
* the default mapping.
*/
public DocumentMapper documentMapper(String type) { public DocumentMapper documentMapper(String type) {
return mappers.get(type); return mappers.get(type);
} }

View File

@ -27,6 +27,7 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -47,10 +48,20 @@ public class FieldTypeLookupTests extends ESTestCase {
assertFalse(itr.hasNext()); assertFalse(itr.hasNext());
} }
public void testDefaultMapping() {
FieldTypeLookup lookup = new FieldTypeLookup();
try {
lookup.copyAndAddAll(MapperService.DEFAULT_MAPPING, Collections.emptyList());
fail();
} catch (IllegalArgumentException expected) {
assertEquals("Default mappings should not be added to the lookup", expected.getMessage());
}
}
public void testAddNewField() { public void testAddNewField() {
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
FakeFieldMapper f = new FakeFieldMapper("foo", "bar"); FakeFieldMapper f = new FakeFieldMapper("foo", "bar");
FieldTypeLookup lookup2 = lookup.copyAndAddAll(newList(f)); FieldTypeLookup lookup2 = lookup.copyAndAddAll("type", newList(f));
assertNull(lookup.get("foo")); assertNull(lookup.get("foo"));
assertNull(lookup.get("bar")); assertNull(lookup.get("bar"));
assertNull(lookup.getByIndexName("foo")); assertNull(lookup.getByIndexName("foo"));
@ -67,8 +78,8 @@ public class FieldTypeLookupTests extends ESTestCase {
MappedFieldType originalFieldType = f.fieldType(); MappedFieldType originalFieldType = f.fieldType();
FakeFieldMapper f2 = new FakeFieldMapper("foo", "foo"); FakeFieldMapper f2 = new FakeFieldMapper("foo", "foo");
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f)); lookup = lookup.copyAndAddAll("type1", newList(f));
FieldTypeLookup lookup2 = lookup.copyAndAddAll(newList(f2)); FieldTypeLookup lookup2 = lookup.copyAndAddAll("type2", newList(f2));
assertNotSame(originalFieldType, f.fieldType()); assertNotSame(originalFieldType, f.fieldType());
assertSame(f.fieldType(), f2.fieldType()); assertSame(f.fieldType(), f2.fieldType());
@ -82,8 +93,8 @@ public class FieldTypeLookupTests extends ESTestCase {
FakeFieldMapper f2 = new FakeFieldMapper("bar", "foo"); FakeFieldMapper f2 = new FakeFieldMapper("bar", "foo");
MappedFieldType originalFieldType = f.fieldType(); MappedFieldType originalFieldType = f.fieldType();
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f)); lookup = lookup.copyAndAddAll("type1", newList(f));
FieldTypeLookup lookup2 = lookup.copyAndAddAll(newList(f2)); FieldTypeLookup lookup2 = lookup.copyAndAddAll("type2", newList(f2));
assertNotSame(originalFieldType, f.fieldType()); assertNotSame(originalFieldType, f.fieldType());
assertSame(f.fieldType(), f2.fieldType()); assertSame(f.fieldType(), f2.fieldType());
@ -98,8 +109,8 @@ public class FieldTypeLookupTests extends ESTestCase {
FakeFieldMapper f2 = new FakeFieldMapper("foo", "bar"); FakeFieldMapper f2 = new FakeFieldMapper("foo", "bar");
MappedFieldType originalFieldType = f.fieldType(); MappedFieldType originalFieldType = f.fieldType();
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f)); lookup = lookup.copyAndAddAll("type1", newList(f));
FieldTypeLookup lookup2 = lookup.copyAndAddAll(newList(f2)); FieldTypeLookup lookup2 = lookup.copyAndAddAll("type2", newList(f2));
assertNotSame(originalFieldType, f.fieldType()); assertNotSame(originalFieldType, f.fieldType());
assertSame(f.fieldType(), f2.fieldType()); assertSame(f.fieldType(), f2.fieldType());
@ -113,18 +124,18 @@ public class FieldTypeLookupTests extends ESTestCase {
FakeFieldMapper f = new FakeFieldMapper("foo", "foo"); FakeFieldMapper f = new FakeFieldMapper("foo", "foo");
FakeFieldMapper f2 = new FakeFieldMapper("bar", "bar"); FakeFieldMapper f2 = new FakeFieldMapper("bar", "bar");
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f, f2)); lookup = lookup.copyAndAddAll("type1", newList(f, f2));
try { try {
FakeFieldMapper f3 = new FakeFieldMapper("foo", "bar"); FakeFieldMapper f3 = new FakeFieldMapper("foo", "bar");
lookup.copyAndAddAll(newList(f3)); lookup.copyAndAddAll("type2", newList(f3));
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
assertTrue(e.getMessage().contains("insane mappings")); assertTrue(e.getMessage().contains("insane mappings"));
} }
try { try {
FakeFieldMapper f3 = new FakeFieldMapper("bar", "foo"); FakeFieldMapper f3 = new FakeFieldMapper("bar", "foo");
lookup.copyAndAddAll(newList(f3)); lookup.copyAndAddAll("type2", newList(f3));
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
assertTrue(e.getMessage().contains("insane mappings")); assertTrue(e.getMessage().contains("insane mappings"));
} }
@ -139,7 +150,7 @@ public class FieldTypeLookupTests extends ESTestCase {
public void testCheckCompatibilityMismatchedTypes() { public void testCheckCompatibilityMismatchedTypes() {
FieldMapper f1 = new FakeFieldMapper("foo", "bar"); FieldMapper f1 = new FakeFieldMapper("foo", "bar");
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f1)); lookup = lookup.copyAndAddAll("type", newList(f1));
MappedFieldType ft2 = FakeFieldMapper.makeOtherFieldType("foo", "foo"); MappedFieldType ft2 = FakeFieldMapper.makeOtherFieldType("foo", "foo");
FieldMapper f2 = new FakeFieldMapper("foo", ft2); FieldMapper f2 = new FakeFieldMapper("foo", ft2);
@ -161,7 +172,7 @@ public class FieldTypeLookupTests extends ESTestCase {
public void testCheckCompatibilityConflict() { public void testCheckCompatibilityConflict() {
FieldMapper f1 = new FakeFieldMapper("foo", "bar"); FieldMapper f1 = new FakeFieldMapper("foo", "bar");
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f1)); lookup = lookup.copyAndAddAll("type", newList(f1));
MappedFieldType ft2 = FakeFieldMapper.makeFieldType("foo", "bar"); MappedFieldType ft2 = FakeFieldMapper.makeFieldType("foo", "bar");
ft2.setBoost(2.0f); ft2.setBoost(2.0f);
@ -196,7 +207,7 @@ public class FieldTypeLookupTests extends ESTestCase {
FakeFieldMapper f1 = new FakeFieldMapper("foo", "baz"); FakeFieldMapper f1 = new FakeFieldMapper("foo", "baz");
FakeFieldMapper f2 = new FakeFieldMapper("bar", "boo"); FakeFieldMapper f2 = new FakeFieldMapper("bar", "boo");
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f1, f2)); lookup = lookup.copyAndAddAll("type", newList(f1, f2));
Collection<String> names = lookup.simpleMatchToIndexNames("b*"); Collection<String> names = lookup.simpleMatchToIndexNames("b*");
assertTrue(names.contains("baz")); assertTrue(names.contains("baz"));
assertTrue(names.contains("boo")); assertTrue(names.contains("boo"));
@ -206,7 +217,7 @@ public class FieldTypeLookupTests extends ESTestCase {
FakeFieldMapper f1 = new FakeFieldMapper("foo", "baz"); FakeFieldMapper f1 = new FakeFieldMapper("foo", "baz");
FakeFieldMapper f2 = new FakeFieldMapper("bar", "boo"); FakeFieldMapper f2 = new FakeFieldMapper("bar", "boo");
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f1, f2)); lookup = lookup.copyAndAddAll("type", newList(f1, f2));
Collection<String> names = lookup.simpleMatchToFullName("b*"); Collection<String> names = lookup.simpleMatchToFullName("b*");
assertTrue(names.contains("foo")); assertTrue(names.contains("foo"));
assertTrue(names.contains("bar")); assertTrue(names.contains("bar"));
@ -215,7 +226,7 @@ public class FieldTypeLookupTests extends ESTestCase {
public void testIteratorImmutable() { public void testIteratorImmutable() {
FakeFieldMapper f1 = new FakeFieldMapper("foo", "bar"); FakeFieldMapper f1 = new FakeFieldMapper("foo", "bar");
FieldTypeLookup lookup = new FieldTypeLookup(); FieldTypeLookup lookup = new FieldTypeLookup();
lookup = lookup.copyAndAddAll(newList(f1)); lookup = lookup.copyAndAddAll("type", newList(f1));
try { try {
Iterator<MappedFieldType> itr = lookup.iterator(); Iterator<MappedFieldType> itr = lookup.iterator();

View File

@ -21,6 +21,8 @@ package org.elasticsearch.index.mapper;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.test.ESSingleNodeTestCase;
import org.junit.Rule; import org.junit.Rule;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
@ -31,6 +33,11 @@ import static org.elasticsearch.test.VersionUtils.randomVersionBetween;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.hasToString;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.concurrent.ExecutionException;
public class MapperServiceTests extends ESSingleNodeTestCase { public class MapperServiceTests extends ESSingleNodeTestCase {
@Rule @Rule
public ExpectedException expectedException = ExpectedException.none(); public ExpectedException expectedException = ExpectedException.none();
@ -82,4 +89,56 @@ public class MapperServiceTests extends ESSingleNodeTestCase {
.execute() .execute()
.actionGet(); .actionGet();
} }
public void testTypes() throws Exception {
IndexService indexService1 = createIndex("index1");
MapperService mapperService = indexService1.mapperService();
assertEquals(Collections.emptySet(), mapperService.types());
mapperService.merge("type1", new CompressedXContent("{\"type1\":{}}"), true, false);
assertNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
assertEquals(Collections.singleton("type1"), mapperService.types());
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent("{\"_default_\":{}}"), true, false);
assertNotNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
assertEquals(Collections.singleton("type1"), mapperService.types());
mapperService.merge("type2", new CompressedXContent("{\"type2\":{}}"), true, false);
assertNotNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
assertEquals(new HashSet<>(Arrays.asList("type1", "type2")), mapperService.types());
}
public void testIndexIntoDefaultMapping() throws Throwable {
// 1. test implicit index creation
try {
client().prepareIndex("index1", MapperService.DEFAULT_MAPPING, "1").setSource("{").execute().get();
fail();
} catch (Throwable t) {
if (t instanceof ExecutionException) {
t = ((ExecutionException) t).getCause();
}
if (t instanceof IllegalArgumentException) {
assertEquals("It is forbidden to index into the default mapping [_default_]", t.getMessage());
} else {
throw t;
}
}
// 2. already existing index
IndexService indexService = createIndex("index2");
try {
client().prepareIndex("index2", MapperService.DEFAULT_MAPPING, "2").setSource().execute().get();
fail();
} catch (Throwable t) {
if (t instanceof ExecutionException) {
t = ((ExecutionException) t).getCause();
}
if (t instanceof IllegalArgumentException) {
assertEquals("It is forbidden to index into the default mapping [_default_]", t.getMessage());
} else {
throw t;
}
}
assertFalse(indexService.mapperService().hasMapping(MapperService.DEFAULT_MAPPING));
}
} }