Merge pull request #14896 from jpountz/fix/mapper_plugins

Register field mappers at the node level.
This commit is contained in:
Adrien Grand 2015-11-24 09:28:06 +01:00
commit 999913443d
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,13 +110,18 @@ 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());
@ -97,7 +111,7 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
.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()
@ -130,7 +144,7 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
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());
}
@ -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());
}
@ -177,10 +191,107 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
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));
}
}