Register field mappers at the node level.

This moves the registration of field mappers from the index level to the node
level and also ensures that mappers coming from plugins are treated no
differently from core mappers.
This commit is contained in:
Adrien Grand 2015-11-20 09:53:55 +01:00
parent 7c104fdb39
commit 5f33fbdb75
50 changed files with 634 additions and 315 deletions

View File

@ -26,12 +26,12 @@ import org.elasticsearch.cluster.routing.UnassignedInfo;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.mapper.MapperRegistry;
import java.util.Collections;
import java.util.Set;
@ -48,9 +48,13 @@ import static org.elasticsearch.common.util.set.Sets.newHashSet;
* are restored from a repository.
*/
public class MetaDataIndexUpgradeService extends AbstractComponent {
private final MapperRegistry mapperRegistry;
@Inject
public MetaDataIndexUpgradeService(Settings settings) {
public MetaDataIndexUpgradeService(Settings settings, MapperRegistry mapperRegistry) {
super(settings);
this.mapperRegistry = mapperRegistry;
}
/**
@ -218,7 +222,7 @@ public class MetaDataIndexUpgradeService extends AbstractComponent {
SimilarityService similarityService = new SimilarityService(indexSettings, Collections.EMPTY_MAP);
try (AnalysisService analysisService = new FakeAnalysisService(indexSettings)) {
try (MapperService mapperService = new MapperService(indexSettings, analysisService, similarityService)) {
try (MapperService mapperService = new MapperService(indexSettings, analysisService, similarityService, mapperRegistry)) {
for (ObjectCursor<MappingMetaData> cursor : indexMetaData.getMappings().values()) {
MappingMetaData mappingMetaData = cursor.value;
mapperService.merge(mappingMetaData.type(), mappingMetaData.source(), false, false);

View File

@ -20,7 +20,6 @@
package org.elasticsearch.index;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.NodeEnvironment;
import org.elasticsearch.index.analysis.AnalysisRegistry;
@ -35,8 +34,8 @@ import org.elasticsearch.index.similarity.SimilarityProvider;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.IndexStore;
import org.elasticsearch.index.store.IndexStoreConfig;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.cache.query.IndicesQueryCache;
import org.elasticsearch.indices.mapper.MapperRegistry;
import java.io.IOException;
import java.util.*;
@ -238,7 +237,7 @@ public final class IndexModule {
IndexSearcherWrapper newWrapper(final IndexService indexService);
}
public IndexService newIndexService(NodeEnvironment environment, IndexService.ShardStoreDeleter shardStoreDeleter, NodeServicesProvider servicesProvider) throws IOException {
public IndexService newIndexService(NodeEnvironment environment, IndexService.ShardStoreDeleter shardStoreDeleter, NodeServicesProvider servicesProvider, MapperRegistry mapperRegistry) throws IOException {
final IndexSettings settings = indexSettings.newWithListener(settingsConsumers);
IndexSearcherWrapperFactory searcherWrapperFactory = indexSearcherWrapper.get() == null ? (shard) -> null : indexSearcherWrapper.get();
IndexEventListener eventListener = freeze();
@ -260,6 +259,6 @@ public final class IndexModule {
final BiFunction<IndexSettings, IndicesQueryCache, QueryCache> queryCacheProvider = queryCaches.get(queryCacheType);
final QueryCache queryCache = queryCacheProvider.apply(settings, servicesProvider.getIndicesQueryCache());
return new IndexService(settings, environment, new SimilarityService(settings, similarities), shardStoreDeleter, analysisRegistry, engineFactory.get(),
servicesProvider, queryCache, store, eventListener, searcherWrapperFactory);
servicesProvider, queryCache, store, eventListener, searcherWrapperFactory, mapperRegistry);
}
}

View File

@ -54,6 +54,7 @@ import org.elasticsearch.index.store.IndexStore;
import org.elasticsearch.index.store.Store;
import org.elasticsearch.indices.AliasFilterParsingException;
import org.elasticsearch.indices.InvalidAliasNameException;
import org.elasticsearch.indices.mapper.MapperRegistry;
import java.io.Closeable;
import java.io.IOException;
@ -102,12 +103,13 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
QueryCache queryCache,
IndexStore indexStore,
IndexEventListener eventListener,
IndexModule.IndexSearcherWrapperFactory wrapperFactory) throws IOException {
IndexModule.IndexSearcherWrapperFactory wrapperFactory,
MapperRegistry mapperRegistry) throws IOException {
super(indexSettings);
this.indexSettings = indexSettings;
this.analysisService = registry.build(indexSettings);
this.similarityService = similarityService;
this.mapperService = new MapperService(indexSettings, analysisService, similarityService);
this.mapperService = new MapperService(indexSettings, analysisService, similarityService, mapperRegistry);
this.indexFieldData = new IndexFieldDataService(indexSettings, nodeServicesProvider.getIndicesFieldDataCache(), nodeServicesProvider.getCircuitBreakerService(), mapperService);
this.shardStoreDeleter = shardStoreDeleter;
this.eventListener = eventListener;

View File

@ -35,8 +35,8 @@ import org.elasticsearch.common.util.concurrent.ReleasableLock;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.mapper.MetadataFieldMapper.TypeParser;
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
import org.elasticsearch.index.mapper.internal.FieldNamesFieldMapper;
import org.elasticsearch.index.mapper.internal.IdFieldMapper;
import org.elasticsearch.index.mapper.internal.IndexFieldMapper;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
@ -46,14 +46,8 @@ import org.elasticsearch.index.mapper.internal.TTLFieldMapper;
import org.elasticsearch.index.mapper.internal.TimestampFieldMapper;
import org.elasticsearch.index.mapper.internal.TypeFieldMapper;
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
import org.elasticsearch.index.mapper.internal.VersionFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
@ -76,7 +70,7 @@ public class DocumentMapper implements ToXContent {
public static class Builder {
private Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> rootMappers = new LinkedHashMap<>();
private Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> metadataMappers = new LinkedHashMap<>();
private final Settings indexSettings;
@ -91,25 +85,12 @@ public class DocumentMapper implements ToXContent {
this.builderContext = new Mapper.BuilderContext(indexSettings, new ContentPath(1));
this.rootObjectMapper = builder.build(builderContext);
// TODO: find a cleaner way to handle existing root mappings and using their field type as the default.
// the vast majority of these root mappers only need the existing type for backwards compatibility, since
// the pre 2.0 field type settings could be modified
// UID first so it will be the first stored field to load (so will benefit from "fields: []" early termination
this.rootMappers.put(UidFieldMapper.class, new UidFieldMapper(indexSettings, mapperService.fullName(UidFieldMapper.NAME)));
this.rootMappers.put(IdFieldMapper.class, new IdFieldMapper(indexSettings, mapperService.fullName(IdFieldMapper.NAME)));
this.rootMappers.put(RoutingFieldMapper.class, new RoutingFieldMapper(indexSettings, mapperService.fullName(RoutingFieldMapper.NAME)));
// add default mappers, order is important (for example analyzer should come before the rest to set context.analyzer)
this.rootMappers.put(IndexFieldMapper.class, new IndexFieldMapper(indexSettings, mapperService.fullName(IndexFieldMapper.NAME)));
this.rootMappers.put(SourceFieldMapper.class, new SourceFieldMapper(indexSettings));
this.rootMappers.put(TypeFieldMapper.class, new TypeFieldMapper(indexSettings, mapperService.fullName(TypeFieldMapper.NAME)));
this.rootMappers.put(AllFieldMapper.class, new AllFieldMapper(indexSettings, mapperService.fullName(AllFieldMapper.NAME)));
this.rootMappers.put(TimestampFieldMapper.class, new TimestampFieldMapper(indexSettings, mapperService.fullName(TimestampFieldMapper.NAME)));
this.rootMappers.put(TTLFieldMapper.class, new TTLFieldMapper(indexSettings));
this.rootMappers.put(VersionFieldMapper.class, new VersionFieldMapper(indexSettings));
this.rootMappers.put(ParentFieldMapper.class, new ParentFieldMapper(indexSettings, mapperService.fullName(ParentFieldMapper.NAME), /* parent type */builder.name()));
// _field_names last so that it can see all other fields
this.rootMappers.put(FieldNamesFieldMapper.class, new FieldNamesFieldMapper(indexSettings, mapperService.fullName(FieldNamesFieldMapper.NAME)));
for (Map.Entry<String, MetadataFieldMapper.TypeParser> entry : mapperService.mapperRegistry.getMetadataMapperParsers().entrySet()) {
final String name = entry.getKey();
final TypeParser parser = entry.getValue();
final MetadataFieldMapper metadataMapper = parser.getDefault(indexSettings, mapperService.fullName(name), builder.name());
metadataMappers.put(metadataMapper.getClass(), metadataMapper);
}
}
public Builder meta(Map<String, Object> meta) {
@ -119,13 +100,13 @@ public class DocumentMapper implements ToXContent {
public Builder put(MetadataFieldMapper.Builder<?, ?> mapper) {
MetadataFieldMapper metadataMapper = mapper.build(builderContext);
rootMappers.put(metadataMapper.getClass(), metadataMapper);
metadataMappers.put(metadataMapper.getClass(), metadataMapper);
return this;
}
public DocumentMapper build(MapperService mapperService, DocumentMapperParser docMapperParser) {
Objects.requireNonNull(rootObjectMapper, "Mapper builder must have the root object mapper set");
return new DocumentMapper(mapperService, indexSettings, docMapperParser, rootObjectMapper, meta, rootMappers, mapperService.mappingLock);
return new DocumentMapper(mapperService, indexSettings, docMapperParser, rootObjectMapper, meta, metadataMappers, mapperService.mappingLock);
}
}
@ -152,7 +133,7 @@ public class DocumentMapper implements ToXContent {
public DocumentMapper(MapperService mapperService, @Nullable Settings indexSettings, DocumentMapperParser docMapperParser,
RootObjectMapper rootObjectMapper,
Map<String, Object> meta,
Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> rootMappers,
Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> metadataMappers,
ReentrantReadWriteLock mappingLock) {
this.mapperService = mapperService;
this.type = rootObjectMapper.name();
@ -160,16 +141,16 @@ public class DocumentMapper implements ToXContent {
this.mapping = new Mapping(
Version.indexCreated(indexSettings),
rootObjectMapper,
rootMappers.values().toArray(new MetadataFieldMapper[rootMappers.values().size()]),
metadataMappers.values().toArray(new MetadataFieldMapper[metadataMappers.values().size()]),
meta);
this.documentParser = new DocumentParser(indexSettings, docMapperParser, this, new ReleasableLock(mappingLock.readLock()));
this.mappingWriteLock = new ReleasableLock(mappingLock.writeLock());
this.mappingLock = mappingLock;
if (rootMapper(ParentFieldMapper.class).active()) {
if (metadataMapper(ParentFieldMapper.class).active()) {
// mark the routing field mapper as required
rootMapper(RoutingFieldMapper.class).markAsRequired();
metadataMapper(RoutingFieldMapper.class).markAsRequired();
}
// collect all the mappers for this type
@ -227,52 +208,52 @@ public class DocumentMapper implements ToXContent {
}
public UidFieldMapper uidMapper() {
return rootMapper(UidFieldMapper.class);
return metadataMapper(UidFieldMapper.class);
}
@SuppressWarnings({"unchecked"})
public <T extends MetadataFieldMapper> T rootMapper(Class<T> type) {
return mapping.rootMapper(type);
public <T extends MetadataFieldMapper> T metadataMapper(Class<T> type) {
return mapping.metadataMapper(type);
}
public IndexFieldMapper indexMapper() {
return rootMapper(IndexFieldMapper.class);
return metadataMapper(IndexFieldMapper.class);
}
public TypeFieldMapper typeMapper() {
return rootMapper(TypeFieldMapper.class);
return metadataMapper(TypeFieldMapper.class);
}
public SourceFieldMapper sourceMapper() {
return rootMapper(SourceFieldMapper.class);
return metadataMapper(SourceFieldMapper.class);
}
public AllFieldMapper allFieldMapper() {
return rootMapper(AllFieldMapper.class);
return metadataMapper(AllFieldMapper.class);
}
public IdFieldMapper idFieldMapper() {
return rootMapper(IdFieldMapper.class);
return metadataMapper(IdFieldMapper.class);
}
public RoutingFieldMapper routingFieldMapper() {
return rootMapper(RoutingFieldMapper.class);
return metadataMapper(RoutingFieldMapper.class);
}
public ParentFieldMapper parentFieldMapper() {
return rootMapper(ParentFieldMapper.class);
return metadataMapper(ParentFieldMapper.class);
}
public TimestampFieldMapper timestampFieldMapper() {
return rootMapper(TimestampFieldMapper.class);
return metadataMapper(TimestampFieldMapper.class);
}
public TTLFieldMapper TTLFieldMapper() {
return rootMapper(TTLFieldMapper.class);
return metadataMapper(TTLFieldMapper.class);
}
public IndexFieldMapper IndexFieldMapper() {
return rootMapper(IndexFieldMapper.class);
return metadataMapper(IndexFieldMapper.class);
}
public Query typeFilter() {

View File

@ -25,7 +25,6 @@ import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.geo.ShapesAvailability;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
@ -34,19 +33,13 @@ import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.core.*;
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
import org.elasticsearch.index.mapper.geo.GeoShapeFieldMapper;
import org.elasticsearch.index.mapper.internal.*;
import org.elasticsearch.index.mapper.ip.IpFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.mapper.MapperRegistry;
import java.util.*;
import static java.util.Collections.unmodifiableMap;
import static java.util.Collections.unmodifiableSortedMap;
import static org.elasticsearch.index.mapper.MapperBuilders.doc;
public class DocumentMapperParser {
@ -59,83 +52,24 @@ public class DocumentMapperParser {
private final RootObjectMapper.TypeParser rootObjectTypeParser = new RootObjectMapper.TypeParser();
private final Object typeParsersMutex = new Object();
private final Version indexVersionCreated;
private final ParseFieldMatcher parseFieldMatcher;
private volatile Map<String, Mapper.TypeParser> typeParsers;
private volatile Map<String, Mapper.TypeParser> rootTypeParsers;
private volatile SortedMap<String, Mapper.TypeParser> additionalRootMappers;
private final Map<String, Mapper.TypeParser> typeParsers;
private final Map<String, MetadataFieldMapper.TypeParser> rootTypeParsers;
public DocumentMapperParser(IndexSettings indexSettings, MapperService mapperService, AnalysisService analysisService,
SimilarityService similarityService) {
SimilarityService similarityService, MapperRegistry mapperRegistry) {
this.indexSettings = indexSettings.getSettings();
this.parseFieldMatcher = new ParseFieldMatcher(this.indexSettings);
this.mapperService = mapperService;
this.analysisService = analysisService;
this.similarityService = similarityService;
Map<String, Mapper.TypeParser> typeParsers = new HashMap<>();
typeParsers.put(ByteFieldMapper.CONTENT_TYPE, new ByteFieldMapper.TypeParser());
typeParsers.put(ShortFieldMapper.CONTENT_TYPE, new ShortFieldMapper.TypeParser());
typeParsers.put(IntegerFieldMapper.CONTENT_TYPE, new IntegerFieldMapper.TypeParser());
typeParsers.put(LongFieldMapper.CONTENT_TYPE, new LongFieldMapper.TypeParser());
typeParsers.put(FloatFieldMapper.CONTENT_TYPE, new FloatFieldMapper.TypeParser());
typeParsers.put(DoubleFieldMapper.CONTENT_TYPE, new DoubleFieldMapper.TypeParser());
typeParsers.put(BooleanFieldMapper.CONTENT_TYPE, new BooleanFieldMapper.TypeParser());
typeParsers.put(BinaryFieldMapper.CONTENT_TYPE, new BinaryFieldMapper.TypeParser());
typeParsers.put(DateFieldMapper.CONTENT_TYPE, new DateFieldMapper.TypeParser());
typeParsers.put(IpFieldMapper.CONTENT_TYPE, new IpFieldMapper.TypeParser());
typeParsers.put(StringFieldMapper.CONTENT_TYPE, new StringFieldMapper.TypeParser());
typeParsers.put(TokenCountFieldMapper.CONTENT_TYPE, new TokenCountFieldMapper.TypeParser());
typeParsers.put(ObjectMapper.CONTENT_TYPE, new ObjectMapper.TypeParser());
typeParsers.put(ObjectMapper.NESTED_CONTENT_TYPE, new ObjectMapper.TypeParser());
typeParsers.put(TypeParsers.MULTI_FIELD_CONTENT_TYPE, TypeParsers.multiFieldConverterTypeParser);
typeParsers.put(CompletionFieldMapper.CONTENT_TYPE, new CompletionFieldMapper.TypeParser());
typeParsers.put(GeoPointFieldMapper.CONTENT_TYPE, new GeoPointFieldMapper.TypeParser());
if (ShapesAvailability.JTS_AVAILABLE) {
typeParsers.put(GeoShapeFieldMapper.CONTENT_TYPE, new GeoShapeFieldMapper.TypeParser());
}
this.typeParsers = unmodifiableMap(typeParsers);
Map<String, Mapper.TypeParser> rootTypeParsers = new HashMap<>();
rootTypeParsers.put(IndexFieldMapper.NAME, new IndexFieldMapper.TypeParser());
rootTypeParsers.put(SourceFieldMapper.NAME, new SourceFieldMapper.TypeParser());
rootTypeParsers.put(TypeFieldMapper.NAME, new TypeFieldMapper.TypeParser());
rootTypeParsers.put(AllFieldMapper.NAME, new AllFieldMapper.TypeParser());
rootTypeParsers.put(ParentFieldMapper.NAME, new ParentFieldMapper.TypeParser());
rootTypeParsers.put(RoutingFieldMapper.NAME, new RoutingFieldMapper.TypeParser());
rootTypeParsers.put(TimestampFieldMapper.NAME, new TimestampFieldMapper.TypeParser());
rootTypeParsers.put(TTLFieldMapper.NAME, new TTLFieldMapper.TypeParser());
rootTypeParsers.put(UidFieldMapper.NAME, new UidFieldMapper.TypeParser());
rootTypeParsers.put(VersionFieldMapper.NAME, new VersionFieldMapper.TypeParser());
rootTypeParsers.put(IdFieldMapper.NAME, new IdFieldMapper.TypeParser());
rootTypeParsers.put(FieldNamesFieldMapper.NAME, new FieldNamesFieldMapper.TypeParser());
this.rootTypeParsers = unmodifiableMap(rootTypeParsers);
additionalRootMappers = Collections.emptySortedMap();
this.typeParsers = mapperRegistry.getMapperParsers();
this.rootTypeParsers = mapperRegistry.getMetadataMapperParsers();
indexVersionCreated = indexSettings.getIndexVersionCreated();
}
public void putTypeParser(String type, Mapper.TypeParser typeParser) {
synchronized (typeParsersMutex) {
Map<String, Mapper.TypeParser> typeParsers = new HashMap<>(this.typeParsers);
typeParsers.put(type, typeParser);
this.typeParsers = unmodifiableMap(typeParsers);
}
}
public void putRootTypeParser(String type, Mapper.TypeParser typeParser) {
synchronized (typeParsersMutex) {
Map<String, Mapper.TypeParser> rootTypeParsers = new HashMap<>(this.rootTypeParsers);
rootTypeParsers.put(type, typeParser);
this.rootTypeParsers = rootTypeParsers;
SortedMap<String, Mapper.TypeParser> additionalRootMappers = new TreeMap<>(this.additionalRootMappers);
additionalRootMappers.put(type, typeParser);
this.additionalRootMappers = unmodifiableSortedMap(additionalRootMappers);
}
}
public Mapper.TypeParser.ParserContext parserContext(String type) {
return new Mapper.TypeParser.ParserContext(type, analysisService, similarityService::getSimilarity, mapperService, typeParsers::get, indexVersionCreated, parseFieldMatcher);
}
@ -148,7 +82,6 @@ public class DocumentMapperParser {
return parse(type, source, null);
}
@SuppressWarnings({"unchecked"})
public DocumentMapper parse(@Nullable String type, String source, String defaultSource) throws MapperParsingException {
Map<String, Object> mapping = null;
if (source != null) {
@ -166,7 +99,6 @@ public class DocumentMapperParser {
return parseCompressed(type, source, null);
}
@SuppressWarnings({"unchecked"})
public DocumentMapper parseCompressed(@Nullable String type, CompressedXContent source, String defaultSource) throws MapperParsingException {
Map<String, Object> mapping = null;
if (source != null) {
@ -198,10 +130,6 @@ public class DocumentMapperParser {
Mapper.TypeParser.ParserContext parserContext = parserContext(type);
// parse RootObjectMapper
DocumentMapper.Builder docBuilder = doc(indexSettings, (RootObjectMapper.Builder) rootObjectTypeParser.parse(type, mapping, parserContext), mapperService);
// Add default mapping for the plugged-in meta mappers
for (Map.Entry<String, Mapper.TypeParser> entry : additionalRootMappers.entrySet()) {
docBuilder.put((MetadataFieldMapper.Builder<?, ?>) entry.getValue().parse(entry.getKey(), Collections.<String, Object>emptyMap(), parserContext));
}
Iterator<Map.Entry<String, Object>> iterator = mapping.entrySet().iterator();
// parse DocumentMapper
while(iterator.hasNext()) {
@ -209,11 +137,11 @@ public class DocumentMapperParser {
String fieldName = Strings.toUnderscoreCase(entry.getKey());
Object fieldNode = entry.getValue();
Mapper.TypeParser typeParser = rootTypeParsers.get(fieldName);
MetadataFieldMapper.TypeParser typeParser = rootTypeParsers.get(fieldName);
if (typeParser != null) {
iterator.remove();
Map<String, Object> fieldNodeMap = (Map<String, Object>) fieldNode;
docBuilder.put((MetadataFieldMapper.Builder) typeParser.parse(fieldName, fieldNodeMap, parserContext));
docBuilder.put(typeParser.parse(fieldName, fieldNodeMap, parserContext));
fieldNodeMap.remove("type");
checkNoRemainingFields(fieldName, fieldNodeMap, parserContext.indexVersionCreated());
}

View File

@ -20,6 +20,7 @@
package org.elasticsearch.index.mapper;
import com.carrotsearch.hppc.ObjectHashSet;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.DelegatingAnalyzerWrapper;
import org.apache.lucene.index.IndexOptions;
@ -45,6 +46,7 @@ import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.InvalidTypeNameException;
import org.elasticsearch.indices.TypeMissingException;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.percolator.PercolatorService;
import org.elasticsearch.script.ScriptService;
@ -104,15 +106,18 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
private volatile Set<String> parentTypes = emptySet();
final MapperRegistry mapperRegistry;
public MapperService(IndexSettings indexSettings, AnalysisService analysisService,
SimilarityService similarityService) {
SimilarityService similarityService, MapperRegistry mapperRegistry) {
super(indexSettings);
this.analysisService = analysisService;
this.fieldTypes = new FieldTypeLookup();
this.documentParser = new DocumentMapperParser(indexSettings, this, analysisService, similarityService);
this.documentParser = new DocumentMapperParser(indexSettings, this, analysisService, similarityService, mapperRegistry);
this.indexAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultIndexAnalyzer(), p -> p.indexAnalyzer());
this.searchAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultSearchAnalyzer(), p -> p.searchAnalyzer());
this.searchQuoteAnalyzer = new MapperAnalyzerWrapper(analysisService.defaultSearchQuoteAnalyzer(), p -> p.searchQuoteAnalyzer());
this.mapperRegistry = mapperRegistry;
this.dynamic = this.indexSettings.getSettings().getAsBoolean("index.mapper.dynamic", true);
defaultPercolatorMappingSource = "{\n" +

View File

@ -46,19 +46,19 @@ public final class Mapping implements ToXContent {
final Version indexCreated;
final RootObjectMapper root;
final MetadataFieldMapper[] metadataMappers;
final Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> rootMappersMap;
final Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> metadataMappersMap;
volatile Map<String, Object> meta;
public Mapping(Version indexCreated, RootObjectMapper rootObjectMapper, MetadataFieldMapper[] metadataMappers, Map<String, Object> meta) {
this.indexCreated = indexCreated;
this.root = rootObjectMapper;
this.metadataMappers = metadataMappers;
Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> rootMappersMap = new HashMap<>();
Map<Class<? extends MetadataFieldMapper>, MetadataFieldMapper> metadataMappersMap = new HashMap<>();
for (MetadataFieldMapper metadataMapper : metadataMappers) {
if (indexCreated.before(Version.V_2_0_0_beta1) && LEGACY_INCLUDE_IN_OBJECT.contains(metadataMapper.name())) {
root.putMapper(metadataMapper);
}
rootMappersMap.put(metadataMapper.getClass(), metadataMapper);
metadataMappersMap.put(metadataMapper.getClass(), metadataMapper);
}
// keep root mappers sorted for consistent serialization
Arrays.sort(metadataMappers, new Comparator<Mapper>() {
@ -67,7 +67,7 @@ public final class Mapping implements ToXContent {
return o1.name().compareTo(o2.name());
}
});
this.rootMappersMap = unmodifiableMap(rootMappersMap);
this.metadataMappersMap = unmodifiableMap(metadataMappersMap);
this.meta = meta;
}
@ -85,8 +85,8 @@ public final class Mapping implements ToXContent {
/** Get the root mapper with the given class. */
@SuppressWarnings("unchecked")
public <T extends MetadataFieldMapper> T rootMapper(Class<T> clazz) {
return (T) rootMappersMap.get(clazz);
public <T extends MetadataFieldMapper> T metadataMapper(Class<T> clazz) {
return (T) metadataMappersMap.get(clazz);
}
/** @see DocumentMapper#merge(Mapping, boolean, boolean) */
@ -95,7 +95,7 @@ public final class Mapping implements ToXContent {
root.merge(mergeWith.root, mergeResult);
for (MetadataFieldMapper metadataMapper : metadataMappers) {
MetadataFieldMapper mergeWithMetadataMapper = mergeWith.rootMapper(metadataMapper.getClass());
MetadataFieldMapper mergeWithMetadataMapper = mergeWith.metadataMapper(metadataMapper.getClass());
if (mergeWithMetadataMapper != null) {
metadataMapper.merge(mergeWithMetadataMapper, mergeResult);
}

View File

@ -23,6 +23,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
import java.io.IOException;
import java.util.Map;
/**
@ -30,6 +31,25 @@ import java.io.IOException;
*/
public abstract class MetadataFieldMapper extends FieldMapper {
public static interface TypeParser extends Mapper.TypeParser {
@Override
MetadataFieldMapper.Builder<?,?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException;
/**
* Get the default {@link MetadataFieldMapper} to use, if nothing had to be parsed.
* @param fieldType null if this is the first root mapper on this index, the existing
* fieldType for this index otherwise
* @param indexSettings the index-level settings
* @param fieldType the existing field type for this meta mapper on the current index
* or null if this is the first type being introduced
* @param typeName the name of the type that this mapper will be used on
*/
// TODO: remove the fieldType parameter which is only used for bw compat with pre-2.0
// since settings could be modified
MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName);
}
public abstract static class Builder<T extends Builder, Y extends MetadataFieldMapper> extends FieldMapper.Builder<T, Y> {
public Builder(String name, MappedFieldType fieldType) {
super(name, fieldType);

View File

@ -113,9 +113,9 @@ public class AllFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder(parserContext.mapperService().fullName(NAME));
// parseField below will happily parse the doc_values setting, but it is then never passed to
@ -150,6 +150,11 @@ public class AllFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new AllFieldMapper(indexSettings, fieldType);
}
}
static final class AllFieldType extends MappedFieldType {
@ -193,11 +198,11 @@ public class AllFieldMapper extends MetadataFieldMapper {
private EnabledAttributeMapper enabledState;
public AllFieldMapper(Settings indexSettings, MappedFieldType existing) {
private AllFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(existing == null ? Defaults.FIELD_TYPE.clone() : existing.clone(), Defaults.ENABLED, indexSettings);
}
protected AllFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled, Settings indexSettings) {
private AllFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled, Settings indexSettings) {
super(NAME, fieldType, Defaults.FIELD_TYPE, indexSettings);
this.enabledState = enabled;

View File

@ -104,9 +104,9 @@ public class FieldNamesFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
if (parserContext.indexVersionCreated().before(Version.V_1_3_0)) {
throw new IllegalArgumentException("type="+CONTENT_TYPE+" is not supported on indices created before version 1.3.0. Is your cluster running multiple datanode versions?");
}
@ -127,6 +127,11 @@ public class FieldNamesFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new FieldNamesFieldMapper(indexSettings, fieldType);
}
}
public static final class FieldNamesFieldType extends MappedFieldType {
@ -200,11 +205,11 @@ public class FieldNamesFieldMapper extends MetadataFieldMapper {
private final boolean pre13Index; // if the index was created before 1.3, _field_names is always disabled
public FieldNamesFieldMapper(Settings indexSettings, MappedFieldType existing) {
private FieldNamesFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(existing == null ? Defaults.FIELD_TYPE.clone() : existing.clone(), indexSettings);
}
public FieldNamesFieldMapper(MappedFieldType fieldType, Settings indexSettings) {
private FieldNamesFieldMapper(MappedFieldType fieldType, Settings indexSettings) {
super(NAME, fieldType, Defaults.FIELD_TYPE, indexSettings);
this.pre13Index = Version.indexCreated(indexSettings).before(Version.V_1_3_0);
if (this.pre13Index) {

View File

@ -112,9 +112,9 @@ public class IdFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
if (parserContext.indexVersionCreated().onOrAfter(Version.V_2_0_0_beta1)) {
throw new MapperParsingException(NAME + " is not configurable");
}
@ -131,6 +131,11 @@ public class IdFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new IdFieldMapper(indexSettings, fieldType);
}
}
static final class IdFieldType extends MappedFieldType {
@ -228,11 +233,11 @@ public class IdFieldMapper extends MetadataFieldMapper {
private final String path;
public IdFieldMapper(Settings indexSettings, MappedFieldType existing) {
private IdFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(idFieldType(indexSettings, existing), Defaults.PATH, indexSettings);
}
protected IdFieldMapper(MappedFieldType fieldType, String path, Settings indexSettings) {
private IdFieldMapper(MappedFieldType fieldType, String path, Settings indexSettings) {
super(NAME, fieldType, Defaults.FIELD_TYPE, indexSettings);
this.path = path;
}

View File

@ -98,9 +98,9 @@ public class IndexFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder(parserContext.mapperService().fullName(NAME));
if (parserContext.indexVersionCreated().onOrAfter(Version.V_2_0_0_beta1)) {
return builder;
@ -119,6 +119,11 @@ public class IndexFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new IndexFieldMapper(indexSettings, fieldType);
}
}
static final class IndexFieldType extends MappedFieldType {
@ -206,11 +211,11 @@ public class IndexFieldMapper extends MetadataFieldMapper {
private EnabledAttributeMapper enabledState;
public IndexFieldMapper(Settings indexSettings, MappedFieldType existing) {
private IndexFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(existing == null ? Defaults.FIELD_TYPE.clone() : existing, Defaults.ENABLED_STATE, indexSettings);
}
public IndexFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabledState, Settings indexSettings) {
private IndexFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabledState, Settings indexSettings) {
super(NAME, fieldType, Defaults.FIELD_TYPE, indexSettings);
this.enabledState = enabledState;
}

View File

@ -129,9 +129,9 @@ public class ParentFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder(parserContext.type());
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String, Object> entry = iterator.next();
@ -155,6 +155,11 @@ public class ParentFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String parentType) {
return new ParentFieldMapper(indexSettings, fieldType, parentType);
}
}
static final class ParentFieldType extends MappedFieldType {
@ -249,7 +254,7 @@ public class ParentFieldMapper extends MetadataFieldMapper {
// has no impact of field data settings, is just here for creating a join field, the parent field mapper in the child type pointing to this type determines the field data settings for this join field
private final MappedFieldType parentJoinFieldType;
protected ParentFieldMapper(MappedFieldType fieldType, MappedFieldType parentJoinFieldType, MappedFieldType childJoinFieldType, String parentType, Settings indexSettings) {
private ParentFieldMapper(MappedFieldType fieldType, MappedFieldType parentJoinFieldType, MappedFieldType childJoinFieldType, String parentType, Settings indexSettings) {
super(NAME, fieldType, Defaults.FIELD_TYPE, indexSettings);
this.parentType = parentType;
this.parentJoinFieldType = parentJoinFieldType;
@ -260,7 +265,7 @@ public class ParentFieldMapper extends MetadataFieldMapper {
}
}
public ParentFieldMapper(Settings indexSettings, MappedFieldType existing, String parentType) {
private ParentFieldMapper(Settings indexSettings, MappedFieldType existing, String parentType) {
this(existing == null ? Defaults.FIELD_TYPE.clone() : existing.clone(), joinFieldTypeForParentType(parentType, indexSettings), null, null, indexSettings);
}

View File

@ -98,9 +98,9 @@ public class RoutingFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder(parserContext.mapperService().fullName(NAME));
if (parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) {
parseField(builder, builder.name, node, parserContext);
@ -119,6 +119,11 @@ public class RoutingFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new RoutingFieldMapper(indexSettings, fieldType);
}
}
static final class RoutingFieldType extends MappedFieldType {
@ -153,11 +158,11 @@ public class RoutingFieldMapper extends MetadataFieldMapper {
private boolean required;
private final String path;
public RoutingFieldMapper(Settings indexSettings, MappedFieldType existing) {
private RoutingFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(existing == null ? Defaults.FIELD_TYPE.clone() : existing.clone(), Defaults.REQUIRED, Defaults.PATH, indexSettings);
}
protected RoutingFieldMapper(MappedFieldType fieldType, boolean required, String path, Settings indexSettings) {
private RoutingFieldMapper(MappedFieldType fieldType, boolean required, String path, Settings indexSettings) {
super(NAME, fieldType, Defaults.FIELD_TYPE, indexSettings);
this.required = required;
this.path = path;

View File

@ -143,9 +143,9 @@ public class SourceFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder();
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
@ -194,6 +194,11 @@ public class SourceFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new SourceFieldMapper(indexSettings);
}
}
static final class SourceFieldType extends MappedFieldType {
@ -248,11 +253,11 @@ public class SourceFieldMapper extends MetadataFieldMapper {
private XContentType formatContentType;
public SourceFieldMapper(Settings indexSettings) {
private SourceFieldMapper(Settings indexSettings) {
this(Defaults.ENABLED, Defaults.FORMAT, null, -1, null, null, indexSettings);
}
protected SourceFieldMapper(boolean enabled, String format, Boolean compress, long compressThreshold,
private SourceFieldMapper(boolean enabled, String format, Boolean compress, long compressThreshold,
String[] includes, String[] excludes, Settings indexSettings) {
super(NAME, Defaults.FIELD_TYPE.clone(), Defaults.FIELD_TYPE, indexSettings); // Only stored.
this.enabled = enabled;

View File

@ -101,9 +101,9 @@ public class TTLFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder();
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String, Object> entry = iterator.next();
@ -123,6 +123,11 @@ public class TTLFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new TTLFieldMapper(indexSettings);
}
}
public static final class TTLFieldType extends LongFieldMapper.LongFieldType {
@ -157,11 +162,11 @@ public class TTLFieldMapper extends MetadataFieldMapper {
private EnabledAttributeMapper enabledState;
private long defaultTTL;
public TTLFieldMapper(Settings indexSettings) {
private TTLFieldMapper(Settings indexSettings) {
this(Defaults.TTL_FIELD_TYPE.clone(), Defaults.ENABLED_STATE, Defaults.DEFAULT, null, indexSettings);
}
protected TTLFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL,
private TTLFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL,
@Nullable Settings fieldDataSettings, Settings indexSettings) {
super(NAME, fieldType, Defaults.TTL_FIELD_TYPE, indexSettings);
this.enabledState = enabled;

View File

@ -165,9 +165,9 @@ public class TimestampFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder(parserContext.mapperService().fullName(NAME));
if (parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) {
parseField(builder, builder.name, node, parserContext);
@ -218,6 +218,11 @@ public class TimestampFieldMapper extends MetadataFieldMapper {
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new TimestampFieldMapper(indexSettings, fieldType);
}
}
public static final class TimestampFieldType extends DateFieldMapper.DateFieldType {
@ -255,11 +260,11 @@ public class TimestampFieldMapper extends MetadataFieldMapper {
private final String defaultTimestamp;
private final Boolean ignoreMissing;
public TimestampFieldMapper(Settings indexSettings, MappedFieldType existing) {
private TimestampFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(chooseFieldType(indexSettings, existing).clone(), chooseFieldType(indexSettings, null), Defaults.ENABLED, Defaults.PATH, Defaults.DEFAULT_TIMESTAMP, null, indexSettings);
}
protected TimestampFieldMapper(MappedFieldType fieldType, MappedFieldType defaultFieldType, EnabledAttributeMapper enabledState, String path,
private TimestampFieldMapper(MappedFieldType fieldType, MappedFieldType defaultFieldType, EnabledAttributeMapper enabledState, String path,
String defaultTimestamp, Boolean ignoreMissing, Settings indexSettings) {
super(NAME, fieldType, defaultFieldType, indexSettings);
this.enabledState = enabledState;

View File

@ -93,9 +93,9 @@ public class TypeFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
if (parserContext.indexVersionCreated().onOrAfter(Version.V_2_0_0_beta1)) {
throw new MapperParsingException(NAME + " is not configurable");
}
@ -103,6 +103,11 @@ public class TypeFieldMapper extends MetadataFieldMapper {
parseField(builder, builder.name, node, parserContext);
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new TypeFieldMapper(indexSettings, fieldType);
}
}
static final class TypeFieldType extends MappedFieldType {
@ -147,12 +152,12 @@ public class TypeFieldMapper extends MetadataFieldMapper {
}
}
public TypeFieldMapper(Settings indexSettings, MappedFieldType existing) {
private TypeFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(existing == null ? defaultFieldType(indexSettings) : existing.clone(),
indexSettings);
}
public TypeFieldMapper(MappedFieldType fieldType, Settings indexSettings) {
private TypeFieldMapper(MappedFieldType fieldType, Settings indexSettings) {
super(NAME, fieldType, defaultFieldType(indexSettings), indexSettings);
}

View File

@ -92,9 +92,9 @@ public class UidFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
if (parserContext.indexVersionCreated().onOrAfter(Version.V_2_0_0_beta1)) {
throw new MapperParsingException(NAME + " is not configurable");
}
@ -102,6 +102,11 @@ public class UidFieldMapper extends MetadataFieldMapper {
parseField(builder, builder.name, node, parserContext);
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new UidFieldMapper(indexSettings, fieldType);
}
}
static final class UidFieldType extends MappedFieldType {
@ -133,11 +138,11 @@ public class UidFieldMapper extends MetadataFieldMapper {
}
}
public UidFieldMapper(Settings indexSettings, MappedFieldType existing) {
private UidFieldMapper(Settings indexSettings, MappedFieldType existing) {
this(existing == null ? Defaults.FIELD_TYPE.clone() : existing, Defaults.FIELD_TYPE, indexSettings);
}
protected UidFieldMapper(MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings) {
private UidFieldMapper(MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings) {
super(NAME, fieldType, defaultFieldType, indexSettings);
}

View File

@ -72,9 +72,9 @@ public class VersionFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder();
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String, Object> entry = iterator.next();
@ -86,6 +86,11 @@ public class VersionFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new VersionFieldMapper(indexSettings);
}
}
static final class VersionFieldType extends MappedFieldType {
@ -118,7 +123,7 @@ public class VersionFieldMapper extends MetadataFieldMapper {
}
}
public VersionFieldMapper(Settings indexSettings) {
private VersionFieldMapper(Settings indexSettings) {
super(NAME, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE, indexSettings);
}

View File

@ -25,6 +25,14 @@ import org.elasticsearch.common.geo.ShapesAvailability;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.util.ExtensionPoint;
import org.elasticsearch.index.NodeServicesProvider;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MetadataFieldMapper;
import org.elasticsearch.index.mapper.core.*;
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
import org.elasticsearch.index.mapper.geo.GeoShapeFieldMapper;
import org.elasticsearch.index.mapper.internal.*;
import org.elasticsearch.index.mapper.ip.IpFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.query.*;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryParser;
import org.elasticsearch.index.termvectors.TermVectorsService;
@ -34,6 +42,7 @@ import org.elasticsearch.indices.cluster.IndicesClusterStateService;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCacheListener;
import org.elasticsearch.indices.flush.SyncedFlushService;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.indices.memory.IndexingMemoryController;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.indices.recovery.RecoverySettings;
@ -43,6 +52,9 @@ import org.elasticsearch.indices.store.IndicesStore;
import org.elasticsearch.indices.store.TransportNodesListShardStoreMetaData;
import org.elasticsearch.indices.ttl.IndicesTTLService;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Configures classes and services that are shared by indices on each node.
*/
@ -52,8 +64,16 @@ public class IndicesModule extends AbstractModule {
private final ExtensionPoint.ClassSet<QueryParser> queryParsers
= new ExtensionPoint.ClassSet<>("query_parser", QueryParser.class);
private final Map<String, Mapper.TypeParser> mapperParsers
= new LinkedHashMap<>();
// Use a LinkedHashMap for metadataMappers because iteration order matters
private final Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers
= new LinkedHashMap<>();
public IndicesModule() {
registerBuiltinQueryParsers();
registerBuiltInMappers();
registerBuiltInMetadataMappers();
}
private void registerBuiltinQueryParsers() {
@ -108,14 +128,77 @@ public class IndicesModule extends AbstractModule {
}
}
private void registerBuiltInMappers() {
registerMapper(ByteFieldMapper.CONTENT_TYPE, new ByteFieldMapper.TypeParser());
registerMapper(ShortFieldMapper.CONTENT_TYPE, new ShortFieldMapper.TypeParser());
registerMapper(IntegerFieldMapper.CONTENT_TYPE, new IntegerFieldMapper.TypeParser());
registerMapper(LongFieldMapper.CONTENT_TYPE, new LongFieldMapper.TypeParser());
registerMapper(FloatFieldMapper.CONTENT_TYPE, new FloatFieldMapper.TypeParser());
registerMapper(DoubleFieldMapper.CONTENT_TYPE, new DoubleFieldMapper.TypeParser());
registerMapper(BooleanFieldMapper.CONTENT_TYPE, new BooleanFieldMapper.TypeParser());
registerMapper(BinaryFieldMapper.CONTENT_TYPE, new BinaryFieldMapper.TypeParser());
registerMapper(DateFieldMapper.CONTENT_TYPE, new DateFieldMapper.TypeParser());
registerMapper(IpFieldMapper.CONTENT_TYPE, new IpFieldMapper.TypeParser());
registerMapper(StringFieldMapper.CONTENT_TYPE, new StringFieldMapper.TypeParser());
registerMapper(TokenCountFieldMapper.CONTENT_TYPE, new TokenCountFieldMapper.TypeParser());
registerMapper(ObjectMapper.CONTENT_TYPE, new ObjectMapper.TypeParser());
registerMapper(ObjectMapper.NESTED_CONTENT_TYPE, new ObjectMapper.TypeParser());
registerMapper(TypeParsers.MULTI_FIELD_CONTENT_TYPE, TypeParsers.multiFieldConverterTypeParser);
registerMapper(CompletionFieldMapper.CONTENT_TYPE, new CompletionFieldMapper.TypeParser());
registerMapper(GeoPointFieldMapper.CONTENT_TYPE, new GeoPointFieldMapper.TypeParser());
if (ShapesAvailability.JTS_AVAILABLE) {
registerMapper(GeoShapeFieldMapper.CONTENT_TYPE, new GeoShapeFieldMapper.TypeParser());
}
}
private void registerBuiltInMetadataMappers() {
// NOTE: the order is important
// UID first so it will be the first stored field to load (so will benefit from "fields: []" early termination
registerMetadataMapper(UidFieldMapper.NAME, new UidFieldMapper.TypeParser());
registerMetadataMapper(IdFieldMapper.NAME, new IdFieldMapper.TypeParser());
registerMetadataMapper(RoutingFieldMapper.NAME, new RoutingFieldMapper.TypeParser());
registerMetadataMapper(IndexFieldMapper.NAME, new IndexFieldMapper.TypeParser());
registerMetadataMapper(SourceFieldMapper.NAME, new SourceFieldMapper.TypeParser());
registerMetadataMapper(TypeFieldMapper.NAME, new TypeFieldMapper.TypeParser());
registerMetadataMapper(AllFieldMapper.NAME, new AllFieldMapper.TypeParser());
registerMetadataMapper(TimestampFieldMapper.NAME, new TimestampFieldMapper.TypeParser());
registerMetadataMapper(TTLFieldMapper.NAME, new TTLFieldMapper.TypeParser());
registerMetadataMapper(VersionFieldMapper.NAME, new VersionFieldMapper.TypeParser());
registerMetadataMapper(ParentFieldMapper.NAME, new ParentFieldMapper.TypeParser());
// _field_names is not registered here, see #getMapperRegistry: we need to register it
// last so that it can see all other mappers, including those coming from plugins
}
public void registerQueryParser(Class<? extends QueryParser> queryParser) {
queryParsers.registerExtension(queryParser);
}
/**
* Register a mapper for the given type.
*/
public synchronized void registerMapper(String type, Mapper.TypeParser parser) {
if (mapperParsers.containsKey(type)) {
throw new IllegalArgumentException("A mapper is already registered for type [" + type + "]");
}
mapperParsers.put(type, parser);
}
/**
* Register a root mapper under the given name.
*/
public synchronized void registerMetadataMapper(String name, MetadataFieldMapper.TypeParser parser) {
if (metadataMapperParsers.containsKey(name)) {
throw new IllegalArgumentException("A mapper is already registered for metadata mapper [" + name + "]");
}
metadataMapperParsers.put(name, parser);
}
@Override
protected void configure() {
bindQueryParsersExtension();
bindMapperExtension();
bind(IndicesService.class).asEagerSingleton();
bind(RecoverySettings.class).asEagerSingleton();
@ -138,6 +221,23 @@ public class IndicesModule extends AbstractModule {
bind(NodeServicesProvider.class).asEagerSingleton();
}
// public for testing
public synchronized MapperRegistry getMapperRegistry() {
// NOTE: we register _field_names here so that it has a chance to see all other
// mappers, including from plugins
if (metadataMapperParsers.containsKey(FieldNamesFieldMapper.NAME)) {
throw new IllegalStateException("Metadata mapper [" + FieldNamesFieldMapper.NAME + "] is already registered");
}
final Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers
= new LinkedHashMap<>(this.metadataMapperParsers);
metadataMapperParsers.put(FieldNamesFieldMapper.NAME, new FieldNamesFieldMapper.TypeParser());
return new MapperRegistry(mapperParsers, metadataMapperParsers);
}
protected void bindMapperExtension() {
bind(MapperRegistry.class).toInstance(getMapperRegistry());
}
protected void bindQueryParsersExtension() {
queryParsers.bind(binder());
bind(IndicesQueriesRegistry.class).asEagerSingleton();

View File

@ -56,6 +56,7 @@ import org.elasticsearch.index.shard.IndexEventListener;
import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.store.IndexStoreConfig;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.node.settings.NodeSettingsService;
import org.elasticsearch.plugins.PluginsService;
@ -91,13 +92,17 @@ public class IndicesService extends AbstractLifecycleComponent<IndicesService> i
private final Map<Index, List<PendingDelete>> pendingDeletes = new HashMap<>();
private final OldShardsStats oldShardsStats = new OldShardsStats();
private final IndexStoreConfig indexStoreConfig;
private final MapperRegistry mapperRegistry;
@Override
protected void doStart() {
}
@Inject
public IndicesService(Settings settings, PluginsService pluginsService, NodeEnvironment nodeEnv, NodeSettingsService nodeSettingsService, AnalysisRegistry analysisRegistry, IndicesQueriesRegistry indicesQueriesRegistry, IndexNameExpressionResolver indexNameExpressionResolver, ClusterService clusterService) {
public IndicesService(Settings settings, PluginsService pluginsService, NodeEnvironment nodeEnv,
NodeSettingsService nodeSettingsService, AnalysisRegistry analysisRegistry,
IndicesQueriesRegistry indicesQueriesRegistry, IndexNameExpressionResolver indexNameExpressionResolver,
ClusterService clusterService, MapperRegistry mapperRegistry) {
super(settings);
this.pluginsService = pluginsService;
this.nodeEnv = nodeEnv;
@ -107,6 +112,7 @@ public class IndicesService extends AbstractLifecycleComponent<IndicesService> i
this.indicesQueriesRegistry = indicesQueriesRegistry;
this.clusterService = clusterService;
this.indexNameExpressionResolver = indexNameExpressionResolver;
this.mapperRegistry = mapperRegistry;
nodeSettingsService.addListener(indexStoreConfig);
}
@ -277,7 +283,7 @@ public class IndicesService extends AbstractLifecycleComponent<IndicesService> i
indexModule.addIndexEventListener(oldShardsStats);
final IndexEventListener listener = indexModule.freeze();
listener.beforeIndexCreated(index, idxSettings.getSettings());
final IndexService indexService = indexModule.newIndexService(nodeEnv, this, nodeServicesProvider);
final IndexService indexService = indexModule.newIndexService(nodeEnv, this, nodeServicesProvider, mapperRegistry);
boolean success = false;
try {
assert indexService.getIndexEventListener() == listener;

View File

@ -0,0 +1,58 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.indices.mapper;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MetadataFieldMapper;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* A registry for all field mappers.
*/
public final class MapperRegistry {
private final Map<String, Mapper.TypeParser> mapperParsers;
private final Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers;
public MapperRegistry(Map<String, Mapper.TypeParser> mapperParsers,
Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers) {
this.mapperParsers = Collections.unmodifiableMap(new LinkedHashMap<>(mapperParsers));
this.metadataMapperParsers = Collections.unmodifiableMap(new LinkedHashMap<>(metadataMapperParsers));
}
/**
* Return a map of the mappers that have been registered. The
* returned map uses the type of the field as a key.
*/
public Map<String, Mapper.TypeParser> getMapperParsers() {
return mapperParsers;
}
/**
* Return a map of the meta mappers that have been registered. The
* returned map uses the name of the field as a key.
*/
public Map<String, MetadataFieldMapper.TypeParser> getMetadataMapperParsers() {
return metadataMapperParsers;
}
}

View File

@ -47,12 +47,14 @@ import org.elasticsearch.index.similarity.SimilarityProvider;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.IndexStore;
import org.elasticsearch.index.store.IndexStoreConfig;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.indices.IndicesWarmer;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.indices.cache.query.IndicesQueryCache;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCacheListener;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.ScriptContextRegistry;
import org.elasticsearch.script.ScriptEngineService;
@ -88,6 +90,7 @@ public class IndexModuleTests extends ESTestCase {
public void addPendingDelete(ShardId shardId, IndexSettings indexSettings) {
}
};
private MapperRegistry mapperRegistry;
static NodeServicesProvider newNodeServiceProvider(Settings settings, Environment environment, Client client, ScriptEngineService... scriptEngineServices) throws IOException {
// TODO this can be used in other place too - lets first refactor the IndicesQueriesRegistry
@ -115,6 +118,7 @@ public class IndexModuleTests extends ESTestCase {
environment = new Environment(settings);
nodeServicesProvider = newNodeServiceProvider(settings, environment, null);
nodeEnvironment = new NodeEnvironment(settings, environment);
mapperRegistry = new IndicesModule().getMapperRegistry();
}
@Override
@ -131,7 +135,7 @@ public class IndexModuleTests extends ESTestCase {
IndexModule module = new IndexModule(indexSettings, null, new AnalysisRegistry(null, environment));
module.setSearcherWrapper((s) -> new Wrapper());
module.engineFactory.set(new MockEngineFactory(AssertingDirectoryReader.class));
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
assertTrue(indexService.getSearcherWrapper() instanceof Wrapper);
assertSame(indexService.getEngineFactory(), module.engineFactory.get());
indexService.close("simon says", false);
@ -144,7 +148,7 @@ public class IndexModuleTests extends ESTestCase {
IndexSettings indexSettings = IndexSettingsModule.newIndexSettings(index, settings);
IndexModule module = new IndexModule(indexSettings, null, new AnalysisRegistry(null, environment));
module.addIndexStore("foo_store", FooStore::new);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
assertTrue(indexService.getIndexStore() instanceof FooStore);
try {
module.addIndexStore("foo_store", FooStore::new);
@ -168,7 +172,7 @@ public class IndexModuleTests extends ESTestCase {
Consumer<Settings> listener = (s) -> {};
module.addIndexSettingsListener(listener);
module.addIndexEventListener(eventListener);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
IndexSettings x = indexService.getIndexSettings();
assertEquals(x.getSettings().getAsMap(), indexSettings.getSettings().getAsMap());
assertEquals(x.getIndex(), index);
@ -198,7 +202,7 @@ public class IndexModuleTests extends ESTestCase {
} catch (IllegalArgumentException ex) {
}
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
IndexSettings x = indexService.getIndexSettings();
assertEquals(1, x.getUpdateListeners().size());
assertSame(x.getUpdateListeners().get(0), listener);
@ -225,7 +229,7 @@ public class IndexModuleTests extends ESTestCase {
}
});
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
SimilarityService similarityService = indexService.similarityService();
assertNotNull(similarityService.getSimilarity("my_similarity"));
assertTrue(similarityService.getSimilarity("my_similarity").get() instanceof TestSimilarity);
@ -242,7 +246,7 @@ public class IndexModuleTests extends ESTestCase {
.build();
IndexModule module = new IndexModule(IndexSettingsModule.newIndexSettings(new Index("foo"), indexSettings), null, new AnalysisRegistry(null, environment));
try {
module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
} catch (IllegalArgumentException ex) {
assertEquals("Unknown Similarity type [test_similarity] for [my_similarity]", ex.getMessage());
}
@ -256,7 +260,7 @@ public class IndexModuleTests extends ESTestCase {
.build();
IndexModule module = new IndexModule(IndexSettingsModule.newIndexSettings(new Index("foo"), indexSettings), null, new AnalysisRegistry(null, environment));
try {
module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
} catch (IllegalArgumentException ex) {
assertEquals("Similarity [my_similarity] must have an associated type", ex.getMessage());
}
@ -303,7 +307,7 @@ public class IndexModuleTests extends ESTestCase {
assertEquals(e.getMessage(), "Can't register the same [query_cache] more than once for [custom]");
}
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
assertTrue(indexService.cache().query() instanceof CustomQueryCache);
indexService.close("simon says", false);
}
@ -313,7 +317,7 @@ public class IndexModuleTests extends ESTestCase {
.put("path.home", createTempDir().toString())
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
IndexModule module = new IndexModule(IndexSettingsModule.newIndexSettings(new Index("foo"), indexSettings), null, new AnalysisRegistry(null, environment));
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider);
IndexService indexService = module.newIndexService(nodeEnvironment, deleter, nodeServicesProvider, mapperRegistry);
assertTrue(indexService.cache().query() instanceof IndexQueryCache);
indexService.close("simon says", false);
}

View File

@ -48,6 +48,7 @@ import org.elasticsearch.index.analysis.AnalysisRegistry;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.IndexSettingsModule;
@ -109,7 +110,8 @@ public class CodecTests extends ESTestCase {
IndexSettings settings = IndexSettingsModule.newIndexSettings(new Index("_na"), nodeSettings);
SimilarityService similarityService = new SimilarityService(settings, Collections.EMPTY_MAP);
AnalysisService analysisService = new AnalysisRegistry(null, new Environment(nodeSettings)).build(settings);
MapperService service = new MapperService(settings, analysisService, similarityService);
MapperRegistry mapperRegistry = new MapperRegistry(Collections.emptyMap(), Collections.emptyMap());
MapperService service = new MapperService(settings, analysisService, similarityService, mapperRegistry);
return new CodecService(service, ESLoggerFactory.getLogger("test"));
}

View File

@ -75,6 +75,8 @@ import org.elasticsearch.index.store.DirectoryUtils;
import org.elasticsearch.index.store.Store;
import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.index.translog.TranslogConfig;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.DummyShardLock;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.IndexSettingsModule;
@ -1901,9 +1903,10 @@ public class InternalEngineTests extends ESTestCase {
IndexSettings indexSettings = IndexSettingsModule.newIndexSettings(index, settings);
AnalysisService analysisService = new AnalysisService(indexSettings, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
SimilarityService similarityService = new SimilarityService(indexSettings, Collections.EMPTY_MAP);
MapperService mapperService = new MapperService(indexSettings, analysisService, similarityService);
MapperRegistry mapperRegistry = new IndicesModule().getMapperRegistry();
MapperService mapperService = new MapperService(indexSettings, analysisService, similarityService, mapperRegistry);
DocumentMapper.Builder b = new DocumentMapper.Builder(settings, rootBuilder, mapperService);
DocumentMapperParser parser = new DocumentMapperParser(indexSettings, mapperService, analysisService, similarityService);
DocumentMapperParser parser = mapperService.documentMapperParser();
this.docMapper = b.build(mapperService, parser);
}

View File

@ -397,7 +397,7 @@ public class SimpleAllMapperTests extends ESSingleNodeTestCase {
}
// issue https://github.com/elasticsearch/elasticsearch/issues/5864
public void testRootMappersStillWorking() {
public void testMetadataMappersStillWorking() {
String mapping = "{";
Map<String, String> rootTypes = new HashMap<>();
//just pick some example from DocumentMapperParser.rootTypeParsers

View File

@ -19,13 +19,9 @@
package org.elasticsearch.index.mapper.externalvalues;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.plugins.Plugin;
import java.io.Closeable;
import java.util.List;
public class ExternalMapperPlugin extends Plugin {
public static final String EXTERNAL = "external";
@ -42,12 +38,11 @@ public class ExternalMapperPlugin extends Plugin {
return "External Mappers Plugin";
}
@Override
public void onIndexService(IndexService indexService) {
final MapperService mapperService = indexService.mapperService();
mapperService.documentMapperParser().putRootTypeParser(ExternalMetadataMapper.CONTENT_TYPE, new ExternalMetadataMapper.TypeParser());
mapperService.documentMapperParser().putTypeParser(EXTERNAL, new ExternalMapper.TypeParser(EXTERNAL, "foo"));
mapperService.documentMapperParser().putTypeParser(EXTERNAL_BIS, new ExternalMapper.TypeParser(EXTERNAL_BIS, "bar"));
mapperService.documentMapperParser().putTypeParser(EXTERNAL_UPPER, new ExternalMapper.TypeParser(EXTERNAL_UPPER, "FOO BAR"));
public void onModule(IndicesModule indicesModule) {
indicesModule.registerMetadataMapper(ExternalMetadataMapper.CONTENT_TYPE, new ExternalMetadataMapper.TypeParser());
indicesModule.registerMapper(EXTERNAL, new ExternalMapper.TypeParser(EXTERNAL, "foo"));
indicesModule.registerMapper(EXTERNAL_BIS, new ExternalMapper.TypeParser(EXTERNAL_BIS, "bar"));
indicesModule.registerMapper(EXTERNAL_UPPER, new ExternalMapper.TypeParser(EXTERNAL_UPPER, "FOO BAR"));
}
}

View File

@ -110,12 +110,17 @@ public class ExternalMetadataMapper extends MetadataFieldMapper {
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
return new Builder();
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new ExternalMetadataMapper(indexSettings);
}
}

View File

@ -24,28 +24,38 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.elasticsearch.test.VersionUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
/**
*/
public class SimpleExternalMappingTests extends ESSingleNodeTestCase {
public void testExternalValues() throws Exception {
Version version = VersionUtils.randomVersionBetween(random(), Version.V_1_0_0, Version.CURRENT);
Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build();
MapperService mapperService = createIndex("test", settings).mapperService();
mapperService.documentMapperParser().putRootTypeParser(ExternalMetadataMapper.CONTENT_TYPE,
new ExternalMetadataMapper.TypeParser());
mapperService.documentMapperParser().putTypeParser(ExternalMapperPlugin.EXTERNAL,
new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "foo"));
IndexService indexService = createIndex("test", settings);
MapperRegistry mapperRegistry = new MapperRegistry(
Collections.singletonMap(ExternalMapperPlugin.EXTERNAL, new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "foo")),
Collections.singletonMap(ExternalMetadataMapper.CONTENT_TYPE, new ExternalMetadataMapper.TypeParser()));
DocumentMapper documentMapper = mapperService.documentMapperParser().parse(
DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
DocumentMapper documentMapper = parser.parse(
XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject(ExternalMetadataMapper.CONTENT_TYPE)
.endObject()
@ -83,11 +93,16 @@ public class SimpleExternalMappingTests extends ESSingleNodeTestCase {
public void testExternalValuesWithMultifield() throws Exception {
Version version = VersionUtils.randomVersionBetween(random(), Version.V_1_0_0, Version.CURRENT);
Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build();
MapperService mapperService = createIndex("test", settings).mapperService();
mapperService.documentMapperParser().putTypeParser(ExternalMapperPlugin.EXTERNAL,
new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "foo"));
IndexService indexService = createIndex("test", settings);
Map<String, Mapper.TypeParser> mapperParsers = new HashMap<>();
mapperParsers.put(ExternalMapperPlugin.EXTERNAL, new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "foo"));
mapperParsers.put(StringFieldMapper.CONTENT_TYPE, new StringFieldMapper.TypeParser());
MapperRegistry mapperRegistry = new MapperRegistry(mapperParsers, Collections.emptyMap());
DocumentMapper documentMapper = mapperService.documentMapperParser().parse(
DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
DocumentMapper documentMapper = parser.parse(
XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
.startObject("field")
.field("type", ExternalMapperPlugin.EXTERNAL)
@ -136,14 +151,17 @@ public class SimpleExternalMappingTests extends ESSingleNodeTestCase {
public void testExternalValuesWithMultifieldTwoLevels() throws Exception {
Version version = VersionUtils.randomVersionBetween(random(), Version.V_1_0_0, Version.CURRENT);
Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build();
MapperService mapperService = createIndex("test", settings).mapperService();
IndexService indexService = createIndex("test", settings);
Map<String, Mapper.TypeParser> mapperParsers = new HashMap<>();
mapperParsers.put(ExternalMapperPlugin.EXTERNAL, new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "foo"));
mapperParsers.put(ExternalMapperPlugin.EXTERNAL_BIS, new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "bar"));
mapperParsers.put(StringFieldMapper.CONTENT_TYPE, new StringFieldMapper.TypeParser());
MapperRegistry mapperRegistry = new MapperRegistry(mapperParsers, Collections.emptyMap());
mapperService.documentMapperParser().putTypeParser(ExternalMapperPlugin.EXTERNAL,
new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "foo"));
mapperService.documentMapperParser().putTypeParser(ExternalMapperPlugin.EXTERNAL_BIS,
new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL_BIS, "bar"));
DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
DocumentMapper documentMapper = mapperService.documentMapperParser().parse(
DocumentMapper documentMapper = parser.parse(
XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
.startObject("field")
.field("type", ExternalMapperPlugin.EXTERNAL)

View File

@ -57,7 +57,7 @@ public class IndexTypeMapperTests extends ESSingleNodeTestCase {
.startObject("_index").field("enabled", false).endObject()
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test", bwcSettings).mapperService().documentMapperParser().parse(mapping);
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
IndexFieldMapper indexMapper = docMapper.metadataMapper(IndexFieldMapper.class);
assertThat(indexMapper.enabled(), equalTo(false));
ParsedDocument doc = docMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
@ -74,7 +74,7 @@ public class IndexTypeMapperTests extends ESSingleNodeTestCase {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
IndexFieldMapper indexMapper = docMapper.metadataMapper(IndexFieldMapper.class);
assertThat(indexMapper.enabled(), equalTo(false));
ParsedDocument doc = docMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
@ -128,7 +128,7 @@ public class IndexTypeMapperTests extends ESSingleNodeTestCase {
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test", bwcSettings).mapperService().documentMapperParser().parse(mapping);
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
IndexFieldMapper indexMapper = docMapper.metadataMapper(IndexFieldMapper.class);
assertThat(indexMapper.enabled(), equalTo(true));
assertThat(indexMapper.fieldType().stored(), equalTo(true));

View File

@ -19,17 +19,31 @@
package org.elasticsearch.index.mapper.internal;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexableField;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.MetadataFieldMapper;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.ESSingleNodeTestCase;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
@ -68,7 +82,7 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
FieldNamesFieldMapper fieldNamesMapper = docMapper.rootMapper(FieldNamesFieldMapper.class);
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertFalse(fieldNamesMapper.fieldType().hasDocValues());
assertEquals(IndexOptions.DOCS, fieldNamesMapper.fieldType().indexOptions());
assertFalse(fieldNamesMapper.fieldType().tokenized());
@ -88,16 +102,16 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
.endObject()
.endObject()
.bytes());
assertFieldNames(set("a", "b", "b.c", "_uid", "_type", "_version", "_source", "_all"), doc);
}
public void testExplicitEnabled() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_field_names").field("enabled", true).endObject()
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
FieldNamesFieldMapper fieldNamesMapper = docMapper.rootMapper(FieldNamesFieldMapper.class);
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertTrue(fieldNamesMapper.fieldType().isEnabled());
ParsedDocument doc = docMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
@ -114,7 +128,7 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
.startObject("_field_names").field("enabled", false).endObject()
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
FieldNamesFieldMapper fieldNamesMapper = docMapper.rootMapper(FieldNamesFieldMapper.class);
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertFalse(fieldNamesMapper.fieldType().isEnabled());
ParsedDocument doc = docMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
@ -122,18 +136,18 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
.field("field", "value")
.endObject()
.bytes());
assertNull(doc.rootDoc().get("_field_names"));
}
public void testPre13Disabled() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
Settings indexSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_2_4.id).build();
DocumentMapper docMapper = createIndex("test", indexSettings).mapperService().documentMapperParser().parse(mapping);
FieldNamesFieldMapper fieldNamesMapper = docMapper.rootMapper(FieldNamesFieldMapper.class);
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertFalse(fieldNamesMapper.fieldType().isEnabled());
}
public void testDisablingBackcompat() throws Exception {
// before 1.5, disabling happened by setting index:no
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
@ -142,7 +156,7 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
Settings indexSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
DocumentMapper docMapper = createIndex("test", indexSettings).mapperService().documentMapperParser().parse(mapping);
FieldNamesFieldMapper fieldNamesMapper = docMapper.rootMapper(FieldNamesFieldMapper.class);
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertFalse(fieldNamesMapper.fieldType().isEnabled());
ParsedDocument doc = docMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
@ -161,7 +175,7 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
Settings indexSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
DocumentMapper docMapper = createIndex("test", indexSettings).mapperService().documentMapperParser().parse(mapping);
FieldNamesFieldMapper fieldNamesMapper = docMapper.rootMapper(FieldNamesFieldMapper.class);
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertTrue(fieldNamesMapper.fieldType().stored());
}
@ -173,14 +187,111 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
.startObject("_field_names").field("enabled", false).endObject()
.endObject().endObject().string();
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
DocumentMapper mapperEnabled = parser.parse(enabledMapping);
DocumentMapper mapperDisabled = parser.parse(disabledMapping);
mapperEnabled.merge(mapperDisabled.mapping(), false, false);
assertFalse(mapperEnabled.rootMapper(FieldNamesFieldMapper.class).fieldType().isEnabled());
assertFalse(mapperEnabled.metadataMapper(FieldNamesFieldMapper.class).fieldType().isEnabled());
mapperEnabled = parser.parse(enabledMapping);
mapperDisabled.merge(mapperEnabled.mapping(), false, false);
assertTrue(mapperEnabled.rootMapper(FieldNamesFieldMapper.class).fieldType().isEnabled());
assertTrue(mapperEnabled.metadataMapper(FieldNamesFieldMapper.class).fieldType().isEnabled());
}
private static class DummyMetadataFieldMapper extends MetadataFieldMapper {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
return new MetadataFieldMapper.Builder<Builder, DummyMetadataFieldMapper>("_dummy", FIELD_TYPE) {
@Override
public DummyMetadataFieldMapper build(BuilderContext context) {
return new DummyMetadataFieldMapper(context.indexSettings());
}
};
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new DummyMetadataFieldMapper(indexSettings);
}
}
private static class DummyFieldType extends MappedFieldType {
public DummyFieldType() {
super();
}
private DummyFieldType(MappedFieldType other) {
super(other);
}
@Override
public MappedFieldType clone() {
return new DummyFieldType(this);
}
@Override
public String typeName() {
return "_dummy";
}
}
private static final MappedFieldType FIELD_TYPE = new DummyFieldType();
static {
FIELD_TYPE.setTokenized(false);
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
FIELD_TYPE.setNames(new MappedFieldType.Names("_dummy"));
FIELD_TYPE.freeze();
}
protected DummyMetadataFieldMapper(Settings indexSettings) {
super("_dummy", FIELD_TYPE, FIELD_TYPE, indexSettings);
}
@Override
public void preParse(ParseContext context) throws IOException {
}
@Override
public void postParse(ParseContext context) throws IOException {
context.doc().add(new Field("_dummy", "dummy", FIELD_TYPE));
}
@Override
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
}
@Override
protected String contentType() {
return "_dummy";
}
}
public void testSeesFieldsFromPlugins() throws IOException {
IndexService indexService = createIndex("test");
IndicesModule indicesModule = new IndicesModule();
indicesModule.registerMetadataMapper("_dummy", new DummyMetadataFieldMapper.TypeParser());
final MapperRegistry mapperRegistry = indicesModule.getMapperRegistry();
MapperService mapperService = new MapperService(indexService.getIndexSettings(), indexService.analysisService(), indexService.similarityService(), mapperRegistry);
DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), mapperService,
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper mapper = parser.parse(mapping);
ParsedDocument parsedDocument = mapper.parse("index", "type", "id", new BytesArray("{}"));
IndexableField[] fields = parsedDocument.rootDoc().getFields(FieldNamesFieldMapper.NAME);
boolean found = false;
for (IndexableField f : fields) {
if ("_dummy".equals(f.stringValue())) {
found = true;
break;
}
}
assertTrue("Could not find the dummy field among " + Arrays.toString(fields), found);
}
}

View File

@ -32,7 +32,7 @@ public class TypeFieldMapperTests extends ESSingleNodeTestCase {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
TypeFieldMapper typeMapper = docMapper.rootMapper(TypeFieldMapper.class);
TypeFieldMapper typeMapper = docMapper.metadataMapper(TypeFieldMapper.class);
assertTrue(typeMapper.fieldType().hasDocValues());
}
@ -42,7 +42,7 @@ public class TypeFieldMapperTests extends ESSingleNodeTestCase {
Settings bwcSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_0_0_beta1.id).build();
DocumentMapper docMapper = createIndex("test", bwcSettings).mapperService().documentMapperParser().parse(mapping);
TypeFieldMapper typeMapper = docMapper.rootMapper(TypeFieldMapper.class);
TypeFieldMapper typeMapper = docMapper.metadataMapper(TypeFieldMapper.class);
assertFalse(typeMapper.fieldType().hasDocValues());
}
}

View File

@ -79,6 +79,7 @@ import org.elasticsearch.indices.IndicesWarmer;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.*;
import org.elasticsearch.script.Script.ScriptParseException;
@ -189,6 +190,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
public void configure() {
// skip services
bindQueryParsersExtension();
bindMapperExtension();
}
},
new ScriptModule(settings) {
@ -239,7 +241,8 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
AnalysisService analysisService = new AnalysisRegistry(null, new Environment(settings)).build(idxSettings);
ScriptService scriptService = injector.getInstance(ScriptService.class);
SimilarityService similarityService = new SimilarityService(idxSettings, Collections.EMPTY_MAP);
MapperService mapperService = new MapperService(idxSettings, analysisService, similarityService);
MapperRegistry mapperRegistry = injector.getInstance(MapperRegistry.class);
MapperService mapperService = new MapperService(idxSettings, analysisService, similarityService, mapperRegistry);
indexFieldDataService = new IndexFieldDataService(idxSettings, injector.getInstance(IndicesFieldDataCache.class), injector.getInstance(CircuitBreakerService.class), mapperService);
BitsetFilterCache bitsetFilterCache = new BitsetFilterCache(idxSettings, new IndicesWarmer(idxSettings.getNodeSettings(), null), new BitsetFilterCache.Listener() {
@Override

View File

@ -52,6 +52,7 @@ import org.elasticsearch.indices.IndicesWarmer;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.ScriptModule;
import org.elasticsearch.script.ScriptService;
@ -119,7 +120,8 @@ public class TemplateQueryParserTests extends ESTestCase {
AnalysisService analysisService = new AnalysisRegistry(null, new Environment(settings)).build(idxSettings);
ScriptService scriptService = injector.getInstance(ScriptService.class);
SimilarityService similarityService = new SimilarityService(idxSettings, Collections.EMPTY_MAP);
MapperService mapperService = new MapperService(idxSettings, analysisService, similarityService);
MapperRegistry mapperRegistry = new IndicesModule().getMapperRegistry();
MapperService mapperService = new MapperService(idxSettings, analysisService, similarityService, mapperRegistry);
IndexFieldDataService indexFieldDataService =new IndexFieldDataService(idxSettings, injector.getInstance(IndicesFieldDataCache.class), injector.getInstance(CircuitBreakerService.class), mapperService);
BitsetFilterCache bitsetFilterCache = new BitsetFilterCache(idxSettings, new IndicesWarmer(idxSettings.getNodeSettings(), null), new BitsetFilterCache.Listener() {
@Override

View File

@ -19,7 +19,7 @@
package org.elasticsearch.mapper.attachments;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.plugins.Plugin;
public class MapperAttachmentsPlugin extends Plugin {
@ -34,8 +34,7 @@ public class MapperAttachmentsPlugin extends Plugin {
return "Adds the attachment type allowing to parse difference attachment formats";
}
@Override
public void onIndexService(IndexService indexService) {
indexService.mapperService().documentMapperParser().putTypeParser("attachment", new AttachmentMapper.TypeParser());
public void onModule(IndicesModule indicesModule) {
indicesModule.registerMapper("attachment", new AttachmentMapper.TypeParser());
}
}

View File

@ -23,7 +23,6 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.mapper.attachments.AttachmentMapper;
import org.junit.Before;
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
@ -39,7 +38,6 @@ public class DateAttachmentMapperTests extends AttachmentUnitTestCase {
@Before
public void setupMapperParser() throws Exception {
mapperParser = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
}
public void testSimpleMappings() throws Exception {

View File

@ -43,7 +43,6 @@ public class EncryptedDocMapperTests extends AttachmentUnitTestCase {
public void testMultipleDocsEncryptedLast() throws IOException {
DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/encrypted/test-mapping.json");
DocumentMapper docMapper = mapperParser.parse(mapping);
@ -74,8 +73,6 @@ public class EncryptedDocMapperTests extends AttachmentUnitTestCase {
public void testMultipleDocsEncryptedFirst() throws IOException {
DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/encrypted/test-mapping.json");
DocumentMapper docMapper = mapperParser.parse(mapping);
byte[] html = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/attachment/test/sample-files/htmlWithValidDateMeta.html");
@ -109,7 +106,6 @@ public class EncryptedDocMapperTests extends AttachmentUnitTestCase {
Settings.builder()
.put("index.mapping.attachment.ignore_errors", false)
.build()).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/encrypted/test-mapping.json");
DocumentMapper docMapper = mapperParser.parse(mapping);

View File

@ -53,7 +53,6 @@ public class LanguageDetectionAttachmentMapperTests extends AttachmentUnitTestCa
Settings.settingsBuilder()
.put("index.mapping.attachment.detect_language", langDetect)
.build()).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/language/language-mapping.json");
docMapper = mapperParser.parse(mapping);

View File

@ -29,6 +29,8 @@ import org.elasticsearch.index.analysis.AnalysisRegistry;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.IndexSettingsModule;
import java.io.IOException;
@ -48,6 +50,9 @@ class MapperTestUtils {
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(new Index("test"), indexSettings);
AnalysisService analysisService = new AnalysisRegistry(null, new Environment(nodeSettings)).build(idxSettings);
SimilarityService similarityService = new SimilarityService(idxSettings, Collections.emptyMap());
return new MapperService(idxSettings, analysisService, similarityService);
IndicesModule indicesModule = new IndicesModule();
indicesModule.registerMapper(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
MapperRegistry mapperRegistry = indicesModule.getMapperRegistry();
return new MapperService(idxSettings, analysisService, similarityService, mapperRegistry);
}
}

View File

@ -45,7 +45,6 @@ public class MetadataMapperTests extends AttachmentUnitTestCase {
.put(otherSettings)
.build();
DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(createTempDir(), settings).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/metadata/test-mapping.json");
DocumentMapper docMapper = mapperParser.parse(mapping);

View File

@ -49,7 +49,6 @@ public class MultifieldAttachmentMapperTests extends AttachmentUnitTestCase {
@Before
public void setupMapperParser() throws Exception {
mapperParser = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
}
@ -94,7 +93,6 @@ public class MultifieldAttachmentMapperTests extends AttachmentUnitTestCase {
threadPool = new ThreadPool("testing-only");
MapperService mapperService = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY);
mapperService.documentMapperParser().putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/multifield/multifield-mapping.json");

View File

@ -26,7 +26,6 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.mapper.attachments.AttachmentMapper;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.StreamsUtils.copyToBytesFromClasspath;
@ -40,7 +39,6 @@ public class SimpleAttachmentMapperTests extends AttachmentUnitTestCase {
public void testSimpleMappings() throws Exception {
DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/simple/test-mapping.json");
DocumentMapper docMapper = mapperParser.parse(mapping);
byte[] html = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/attachment/test/sample-files/testXHTML.html");
@ -70,7 +68,6 @@ public class SimpleAttachmentMapperTests extends AttachmentUnitTestCase {
Settings.builder()
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id)
.build()).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/simple/test-mapping.json");
DocumentMapper docMapper = mapperParser.parse(mapping);
byte[] html = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/attachment/test/sample-files/testXHTML.html");
@ -86,7 +83,6 @@ public class SimpleAttachmentMapperTests extends AttachmentUnitTestCase {
*/
public void testSimpleMappingsWithAllFields() throws Exception {
DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/simple/test-mapping-all-fields.json");
DocumentMapper docMapper = mapperParser.parse(mapping);
byte[] html = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/attachment/test/sample-files/testXHTML.html");

View File

@ -89,7 +89,6 @@ public class StandaloneRunner extends CliTool {
this.url = url;
this.base64text = base64text;
DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(PathUtils.get("."), Settings.EMPTY).documentMapperParser(); // use CWD b/c it won't be used
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/standalone/standalone-mapping.json");
docMapper = mapperParser.parse(mapping);

View File

@ -49,7 +49,6 @@ public class VariousDocTests extends AttachmentUnitTestCase {
@Before
public void createMapper() throws IOException {
DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(createTempDir(), Settings.EMPTY).documentMapperParser();
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/unit/various-doc/test-mapping.json");
docMapper = mapperParser.parse(mapping);

View File

@ -19,13 +19,10 @@
package org.elasticsearch.plugin.mapper;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.murmur3.Murmur3FieldMapper;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.plugins.Plugin;
import java.io.Closeable;
import java.util.List;
public class MapperMurmur3Plugin extends Plugin {
@Override
@ -38,9 +35,8 @@ public class MapperMurmur3Plugin extends Plugin {
return "A mapper that allows to precompute murmur3 hashes of values at index-time and store them in the index";
}
@Override
public void onIndexService(IndexService indexService) {
indexService.mapperService().documentMapperParser().putTypeParser(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser());
public void onModule(IndicesModule indicesModule) {
indicesModule.registerMapper(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser());
}
}

View File

@ -31,21 +31,27 @@ import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.junit.Before;
import java.util.Arrays;
import java.util.Collections;
public class Murmur3FieldMapperTests extends ESSingleNodeTestCase {
MapperRegistry mapperRegistry;
IndexService indexService;
DocumentMapperParser parser;
@Before
public void before() {
indexService = createIndex("test");
parser = indexService.mapperService().documentMapperParser();
parser.putTypeParser(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser());
mapperRegistry = new MapperRegistry(
Collections.singletonMap(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser()),
Collections.emptyMap());
parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
}
public void testDefaults() throws Exception {
@ -120,8 +126,8 @@ public class Murmur3FieldMapperTests extends ESSingleNodeTestCase {
public void testDocValuesSettingBackcompat() throws Exception {
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
indexService = createIndex("test_bwc", settings);
parser = indexService.mapperService().documentMapperParser();
parser.putTypeParser(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser());
parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("field")
.field("type", "murmur3")
@ -136,8 +142,8 @@ public class Murmur3FieldMapperTests extends ESSingleNodeTestCase {
public void testIndexSettingBackcompat() throws Exception {
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
indexService = createIndex("test_bwc", settings);
parser = indexService.mapperService().documentMapperParser();
parser.putTypeParser(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser());
parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("field")
.field("type", "murmur3")

View File

@ -85,9 +85,9 @@ public class SizeFieldMapper extends MetadataFieldMapper {
}
}
public static class TypeParser implements Mapper.TypeParser {
public static class TypeParser implements MetadataFieldMapper.TypeParser {
@Override
public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
public MetadataFieldMapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Builder builder = new Builder(parserContext.mapperService().fullName(NAME));
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String, Object> entry = iterator.next();
@ -103,10 +103,19 @@ public class SizeFieldMapper extends MetadataFieldMapper {
}
return builder;
}
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
return new SizeFieldMapper(indexSettings, fieldType);
}
}
private EnabledAttributeMapper enabledState;
private SizeFieldMapper(Settings indexSettings, MappedFieldType mappedFieldType) {
this(Defaults.ENABLED_STATE, mappedFieldType == null ? Defaults.SIZE_FIELD_TYPE : mappedFieldType, indexSettings);
}
private SizeFieldMapper(EnabledAttributeMapper enabled, MappedFieldType fieldType, Settings indexSettings) {
super(NAME, fieldType, Defaults.SIZE_FIELD_TYPE, indexSettings);
this.enabledState = enabled;

View File

@ -19,13 +19,10 @@
package org.elasticsearch.plugin.mapper;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.size.SizeFieldMapper;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.plugins.Plugin;
import java.io.Closeable;
import java.util.List;
public class MapperSizePlugin extends Plugin {
@Override
@ -38,10 +35,7 @@ public class MapperSizePlugin extends Plugin {
return "A mapper that allows document to record their uncompressed size";
}
@Override
public void onIndexService(IndexService indexService) {
indexService.mapperService().documentMapperParser().putRootTypeParser(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser());
public void onModule(IndicesModule indicesModule) {
indicesModule.registerMetadataMapper(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser());
}
}

View File

@ -19,27 +19,47 @@
package org.elasticsearch.index.mapper.size;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import java.util.Collections;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.mapper.SourceToParse;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.ESSingleNodeTestCase;
import static org.hamcrest.Matchers.*;
import org.junit.Before;
public class SizeMappingTests extends ESSingleNodeTestCase {
MapperRegistry mapperRegistry;
IndexService indexService;
DocumentMapperParser parser;
@Before
public void before() {
indexService = createIndex("test");
mapperRegistry = new MapperRegistry(
Collections.emptyMap(),
Collections.singletonMap(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser()));
parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
}
public void testSizeEnabled() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_size").field("enabled", true).endObject()
.endObject().endObject().string();
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
parser.putRootTypeParser(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser());
DocumentMapper docMapper = parser.parse(mapping);
BytesReference source = XContentFactory.jsonBuilder()
@ -59,8 +79,12 @@ public class SizeMappingTests extends ESSingleNodeTestCase {
.endObject().endObject().string();
Settings indexSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
DocumentMapperParser parser = createIndex("test", indexSettings).mapperService().documentMapperParser();
parser.putRootTypeParser(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser());
indexService = createIndex("test2", indexSettings);
mapperRegistry = new MapperRegistry(
Collections.emptyMap(),
Collections.singletonMap(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser()));
parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.analysisService(), indexService.similarityService(), mapperRegistry);
DocumentMapper docMapper = parser.parse(mapping);
BytesReference source = XContentFactory.jsonBuilder()
@ -78,8 +102,6 @@ public class SizeMappingTests extends ESSingleNodeTestCase {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_size").field("enabled", false).endObject()
.endObject().endObject().string();
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
parser.putRootTypeParser(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser());
DocumentMapper docMapper = parser.parse(mapping);
BytesReference source = XContentFactory.jsonBuilder()
@ -95,7 +117,7 @@ public class SizeMappingTests extends ESSingleNodeTestCase {
public void testSizeNotSet() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
DocumentMapper docMapper = parser.parse(mapping);
BytesReference source = XContentFactory.jsonBuilder()
.startObject()
@ -111,8 +133,6 @@ public class SizeMappingTests extends ESSingleNodeTestCase {
String enabledMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_size").field("enabled", true).endObject()
.endObject().endObject().string();
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
parser.putRootTypeParser(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser());
DocumentMapper enabledMapper = parser.parse(enabledMapping);
String disabledMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
@ -121,6 +141,6 @@ public class SizeMappingTests extends ESSingleNodeTestCase {
DocumentMapper disabledMapper = parser.parse(disabledMapping);
enabledMapper.merge(disabledMapper.mapping(), false, false);
assertThat(enabledMapper.rootMapper(SizeFieldMapper.class).enabled(), is(false));
assertThat(enabledMapper.metadataMapper(SizeFieldMapper.class).enabled(), is(false));
}
}