Mappings: Remove traverse functions from Mapper

The mapper listener abstractions for object and field mappers are used
to notify the mapper service of new fields, as well as collect
all object and field mappers through a set of traversal functions.

This change removes the traversal functions in favor of simple
iteration over subfields of a mapper.
This commit is contained in:
Ryan Ernst 2015-05-06 23:07:07 -07:00
parent 82c21ff5b3
commit 0b31efb328
11 changed files with 106 additions and 151 deletions

View File

@ -19,10 +19,10 @@
package org.elasticsearch.index.mapper; package org.elasticsearch.index.mapper;
import com.google.common.base.Function;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSet;
@ -207,27 +207,24 @@ public class DocumentMapper implements ToXContent {
rootMapper(RoutingFieldMapper.class).markAsRequired(); rootMapper(RoutingFieldMapper.class).markAsRequired();
} }
FieldMapperListener.Aggregator fieldMappersAgg = new FieldMapperListener.Aggregator(); // collect all the mappers for this type
for (RootMapper rootMapper : this.mapping.rootMappers) { List<ObjectMapper> newObjectMappers = new ArrayList<>();
List<FieldMapper<?>> newFieldMappers = new ArrayList<>();
for (RootMapper rootMapper : this.mapping.rootMappersNotIncludedInObject) {
if (rootMapper instanceof FieldMapper) { if (rootMapper instanceof FieldMapper) {
fieldMappersAgg.mappers.add((FieldMapper) rootMapper); newFieldMappers.add((FieldMapper) rootMapper);
} }
} }
MapperUtils.collect(this.mapping.root, newObjectMappers, newFieldMappers);
// now traverse and get all the statically defined ones this.fieldMappers = new DocumentFieldMappers(docMapperParser.analysisService).copyAndAllAll(newFieldMappers);
rootObjectMapper.traverse(fieldMappersAgg); this.objectMappers = Maps.uniqueIndex(newObjectMappers, new Function<ObjectMapper, String>() {
this.fieldMappers = new DocumentFieldMappers(docMapperParser.analysisService).copyAndAllAll(fieldMappersAgg.mappers);
final Map<String, ObjectMapper> objectMappers = Maps.newHashMap();
rootObjectMapper.traverse(new ObjectMapperListener() {
@Override @Override
public void objectMapper(ObjectMapper objectMapper) { public String apply(ObjectMapper mapper) {
objectMappers.put(objectMapper.fullPath(), objectMapper); return mapper.fullPath();
} }
}); });
this.objectMappers = ImmutableMap.copyOf(objectMappers); for (ObjectMapper objectMapper : newObjectMappers) {
for (ObjectMapper objectMapper : objectMappers.values()) {
if (objectMapper.nested().isNested()) { if (objectMapper.nested().isNested()) {
hasNestedObjects = true; hasNestedObjects = true;
} }
@ -426,20 +423,7 @@ public class DocumentMapper implements ToXContent {
fieldMapperListeners.add(fieldMapperListener); fieldMapperListeners.add(fieldMapperListener);
} }
public void traverse(FieldMapperListener listener) { private void addObjectMappers(Collection<ObjectMapper> objectMappers) {
for (RootMapper rootMapper : mapping.rootMappers) {
if (!rootMapper.includeInObject() && rootMapper instanceof FieldMapper) {
listener.fieldMapper((FieldMapper) rootMapper);
}
}
mapping.root.traverse(listener);
}
public void addObjectMappers(Collection<ObjectMapper> objectMappers) {
addObjectMappers(objectMappers.toArray(new ObjectMapper[objectMappers.size()]));
}
private void addObjectMappers(ObjectMapper... objectMappers) {
synchronized (mappersMutex) { synchronized (mappersMutex) {
MapBuilder<String, ObjectMapper> builder = MapBuilder.newMapBuilder(this.objectMappers); MapBuilder<String, ObjectMapper> builder = MapBuilder.newMapBuilder(this.objectMappers);
for (ObjectMapper objectMapper : objectMappers) { for (ObjectMapper objectMapper : objectMappers) {
@ -459,10 +443,6 @@ public class DocumentMapper implements ToXContent {
objectMapperListeners.add(objectMapperListener); objectMapperListeners.add(objectMapperListener);
} }
public void traverse(ObjectMapperListener listener) {
mapping.root.traverse(listener);
}
private MergeResult newMergeContext(boolean simulate) { private MergeResult newMergeContext(boolean simulate) {
return new MergeResult(simulate) { return new MergeResult(simulate) {

View File

@ -20,7 +20,6 @@
package org.elasticsearch.index.mapper; package org.elasticsearch.index.mapper;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
@ -29,17 +28,13 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.index.analysis.AnalysisService; import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityLookupService;
import java.io.IOException;
import java.util.Map; import java.util.Map;
/** public interface Mapper extends ToXContent, Iterable<Mapper> {
*
*/
public interface Mapper extends ToXContent {
public static final Mapper[] EMPTY_ARRAY = new Mapper[0]; Mapper[] EMPTY_ARRAY = new Mapper[0];
public static class BuilderContext { class BuilderContext {
private final Settings indexSettings; private final Settings indexSettings;
private final ContentPath contentPath; private final ContentPath contentPath;
@ -66,7 +61,7 @@ public interface Mapper extends ToXContent {
} }
} }
public static abstract class Builder<T extends Builder, Y extends Mapper> { abstract class Builder<T extends Builder, Y extends Mapper> {
public String name; public String name;
@ -83,9 +78,9 @@ public interface Mapper extends ToXContent {
public abstract Y build(BuilderContext context); public abstract Y build(BuilderContext context);
} }
public interface TypeParser { interface TypeParser {
public static class ParserContext { class ParserContext {
private final AnalysisService analysisService; private final AnalysisService analysisService;
@ -127,9 +122,5 @@ public interface Mapper extends ToXContent {
void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException; void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException;
void traverse(FieldMapperListener fieldMapperListener);
void traverse(ObjectMapperListener objectMapperListener);
void close(); void close();
} }

View File

@ -61,6 +61,7 @@ import org.elasticsearch.percolator.PercolatorService;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -265,14 +266,17 @@ public class MapperService extends AbstractIndexComponent {
fieldDataService.onMappingUpdate(); fieldDataService.onMappingUpdate();
return oldMapper; return oldMapper;
} else { } else {
FieldMapperListener.Aggregator fieldMappersAgg = new FieldMapperListener.Aggregator(); List<ObjectMapper> newObjectMappers = new ArrayList<>();
mapper.traverse(fieldMappersAgg); List<FieldMapper<?>> newFieldMappers = new ArrayList<>();
addFieldMappers(fieldMappersAgg.mappers); for (RootMapper rootMapper : mapper.mapping().rootMappers) {
if (!rootMapper.includeInObject() && rootMapper instanceof FieldMapper) {
newFieldMappers.add((FieldMapper<?>) rootMapper);
}
}
MapperUtils.collect(mapper.mapping().root, newObjectMappers, newFieldMappers);
addFieldMappers(newFieldMappers);
mapper.addFieldMapperListener(fieldMapperListener); mapper.addFieldMapperListener(fieldMapperListener);
addObjectMappers(newObjectMappers);
ObjectMapperListener.Aggregator objectMappersAgg = new ObjectMapperListener.Aggregator();
mapper.traverse(objectMappersAgg);
addObjectMappers(objectMappersAgg.mappers.toArray(new ObjectMapper[objectMappersAgg.mappers.size()]));
mapper.addObjectMapperListener(objectMapperListener); mapper.addObjectMapperListener(objectMapperListener);
for (DocumentTypeListener typeListener : typeListeners) { for (DocumentTypeListener typeListener : typeListeners) {
@ -284,7 +288,7 @@ public class MapperService extends AbstractIndexComponent {
} }
} }
private void addObjectMappers(ObjectMapper[] objectMappers) { private void addObjectMappers(Collection<ObjectMapper> objectMappers) {
synchronized (mappersMutex) { synchronized (mappersMutex) {
ImmutableOpenMap.Builder<String, ObjectMappers> fullPathObjectMappers = ImmutableOpenMap.builder(this.fullPathObjectMappers); ImmutableOpenMap.Builder<String, ObjectMappers> fullPathObjectMappers = ImmutableOpenMap.builder(this.fullPathObjectMappers);
for (ObjectMapper objectMapper : objectMappers) { for (ObjectMapper objectMapper : objectMappers) {
@ -860,11 +864,11 @@ public class MapperService extends AbstractIndexComponent {
class InternalObjectMapperListener extends ObjectMapperListener { class InternalObjectMapperListener extends ObjectMapperListener {
@Override @Override
public void objectMapper(ObjectMapper objectMapper) { public void objectMapper(ObjectMapper objectMapper) {
addObjectMappers(new ObjectMapper[]{objectMapper}); addObjectMappers(Collections.singletonList(objectMapper));
} }
@Override @Override
public void objectMappers(ObjectMapper... objectMappers) { public void objectMappers(Collection<ObjectMapper> objectMappers) {
addObjectMappers(objectMappers); addObjectMappers(objectMappers);
} }
} }

View File

@ -21,6 +21,7 @@ package org.elasticsearch.index.mapper;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.index.mapper.object.ObjectMapper; import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
@ -28,8 +29,6 @@ import java.util.Collection;
public enum MapperUtils { public enum MapperUtils {
; ;
private static MergeResult newStrictMergeContext() { private static MergeResult newStrictMergeContext() {
return new MergeResult(false) { return new MergeResult(false) {
@ -76,4 +75,17 @@ public enum MapperUtils {
mergeInto.merge(mergeWith, newStrictMergeContext()); mergeInto.merge(mergeWith, newStrictMergeContext());
} }
/** Split mapper and its descendants into object and field mappers. */
public static void collect(Mapper mapper, Collection<ObjectMapper> objectMappers, Collection<FieldMapper<?>> fieldMappers) {
if (mapper instanceof RootObjectMapper) {
// root mapper isn't really an object mapper
} else if (mapper instanceof ObjectMapper) {
objectMappers.add((ObjectMapper)mapper);
} else if (mapper instanceof FieldMapper<?>) {
fieldMappers.add((FieldMapper<?>)mapper);
}
for (Mapper child : mapper) {
collect(child, objectMappers, fieldMappers);
}
}
} }

View File

@ -22,11 +22,9 @@ package org.elasticsearch.index.mapper;
import org.elasticsearch.index.mapper.object.ObjectMapper; import org.elasticsearch.index.mapper.object.ObjectMapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
/**
*
*/
public abstract class ObjectMapperListener { public abstract class ObjectMapperListener {
public static class Aggregator extends ObjectMapperListener { public static class Aggregator extends ObjectMapperListener {
@ -40,7 +38,7 @@ public abstract class ObjectMapperListener {
public abstract void objectMapper(ObjectMapper objectMapper); public abstract void objectMapper(ObjectMapper objectMapper);
public void objectMappers(ObjectMapper... objectMappers) { public void objectMappers(Collection<ObjectMapper> objectMappers) {
for (ObjectMapper objectMapper : objectMappers) { for (ObjectMapper objectMapper : objectMappers) {
objectMapper(objectMapper); objectMapper(objectMapper);
} }

View File

@ -22,14 +22,16 @@ package org.elasticsearch.index.mapper.core;
import com.carrotsearch.hppc.ObjectOpenHashSet; import com.carrotsearch.hppc.ObjectOpenHashSet;
import com.carrotsearch.hppc.cursors.ObjectCursor; import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.google.common.base.Function;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.queries.TermsQuery; import org.apache.lucene.queries.TermsQuery;
import org.apache.lucene.search.Filter; import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.FuzzyQuery;
@ -40,7 +42,6 @@ import org.apache.lucene.search.QueryWrapperFilter;
import org.apache.lucene.search.RegexpQuery; import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery; import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.index.Terms;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.action.fieldstats.FieldStats; import org.elasticsearch.action.fieldstats.FieldStats;
@ -55,11 +56,14 @@ import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.fielddata.FieldDataType; import org.elasticsearch.index.fielddata.FieldDataType;
import org.elasticsearch.index.mapper.*; import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.ParseContext.Document; import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.internal.AllFieldMapper; import org.elasticsearch.index.mapper.internal.AllFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.search.FieldDataTermsFilter; import org.elasticsearch.index.search.FieldDataTermsFilter;
import org.elasticsearch.index.similarity.SimilarityLookupService; import org.elasticsearch.index.similarity.SimilarityLookupService;
@ -68,7 +72,9 @@ import org.elasticsearch.index.similarity.SimilarityProvider;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.TreeMap; import java.util.TreeMap;
@ -444,15 +450,11 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
return false; return false;
} }
@Override public Iterator<Mapper> iterator() {
public void traverse(FieldMapperListener fieldMapperListener) { if (multiFields == null) {
fieldMapperListener.fieldMapper(this); return Collections.emptyIterator();
multiFields.traverse(fieldMapperListener);
} }
return multiFields.iterator();
@Override
public void traverse(ObjectMapperListener objectMapperListener) {
// nothing to do here...
} }
@Override @Override
@ -955,10 +957,13 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
} }
} }
public void traverse(FieldMapperListener fieldMapperListener) { public Iterator<Mapper> iterator() {
for (ObjectCursor<FieldMapper> cursor : mappers.values()) { return Iterators.transform(mappers.values().iterator(), new Function<ObjectCursor<FieldMapper>, Mapper>() {
cursor.value.traverse(fieldMapperListener); @Override
public Mapper apply(@Nullable ObjectCursor<FieldMapper> cursor) {
return cursor.value;
} }
});
} }
public void close() { public void close() {

View File

@ -22,7 +22,7 @@ package org.elasticsearch.index.mapper.geo;
import com.carrotsearch.hppc.ObjectOpenHashSet; import com.carrotsearch.hppc.ObjectOpenHashSet;
import com.carrotsearch.hppc.cursors.ObjectCursor; import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.Iterators;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.DocValuesType;
@ -45,12 +45,10 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.fielddata.FieldDataType; import org.elasticsearch.index.fielddata.FieldDataType;
import org.elasticsearch.index.mapper.ContentPath; import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.FieldMapperListener;
import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.MergeMappingException; import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.ObjectMapperListener; import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.core.AbstractFieldMapper; import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
import org.elasticsearch.index.mapper.core.DoubleFieldMapper; import org.elasticsearch.index.mapper.core.DoubleFieldMapper;
@ -61,6 +59,7 @@ import org.elasticsearch.index.mapper.object.ArrayValueMapperParser;
import org.elasticsearch.index.similarity.SimilarityProvider; import org.elasticsearch.index.similarity.SimilarityProvider;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -678,19 +677,16 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
} }
@Override @Override
public void traverse(FieldMapperListener fieldMapperListener) { public Iterator<Mapper> iterator() {
super.traverse(fieldMapperListener); List<Mapper> extras = new ArrayList<>();
if (enableGeoHash) { if (enableGeoHash) {
geohashMapper.traverse(fieldMapperListener); extras.add(geohashMapper);
} }
if (enableLatLon) { if (enableLatLon) {
latMapper.traverse(fieldMapperListener); extras.add(latMapper);
lonMapper.traverse(fieldMapperListener); extras.add(lonMapper);
} }
} return Iterators.concat(super.iterator(), extras.iterator());
@Override
public void traverse(ObjectMapperListener objectMapperListener) {
} }
@Override @Override

View File

@ -36,10 +36,12 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.mapper.ContentPath; import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser; import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.FieldMapperListener; import org.elasticsearch.index.mapper.FieldMapperListener;
import org.elasticsearch.index.mapper.InternalMapper; import org.elasticsearch.index.mapper.InternalMapper;
import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MapperUtils;
import org.elasticsearch.index.mapper.MergeMappingException; import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.MergeResult; import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.ObjectMapperListener; import org.elasticsearch.index.mapper.ObjectMapperListener;
@ -468,18 +470,8 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll, Clonea
} }
@Override @Override
public void traverse(FieldMapperListener fieldMapperListener) { public Iterator<Mapper> iterator() {
for (Mapper mapper : mappers.values()) { return mappers.values().iterator();
mapper.traverse(fieldMapperListener);
}
}
@Override
public void traverse(ObjectMapperListener objectMapperListener) {
objectMapperListener.objectMapper(this);
for (Mapper mapper : mappers.values()) {
mapper.traverse(objectMapperListener);
}
} }
public String fullPath() { public String fullPath() {
@ -523,27 +515,26 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll, Clonea
doMerge(mergeWithObject, mergeResult); doMerge(mergeWithObject, mergeResult);
List<Mapper> mappersToPut = new ArrayList<>(); List<Mapper> mappersToPut = new ArrayList<>();
FieldMapperListener.Aggregator newFieldMappers = new FieldMapperListener.Aggregator(); List<ObjectMapper> newObjectMappers = new ArrayList<>();
ObjectMapperListener.Aggregator newObjectMappers = new ObjectMapperListener.Aggregator(); List<FieldMapper<?>> newFieldMappers = new ArrayList<>();
for (Mapper mapper : mergeWithObject.mappers.values()) { for (Mapper mapper : mergeWithObject) {
Mapper mergeWithMapper = mapper; Mapper mergeWithMapper = mapper;
Mapper mergeIntoMapper = mappers.get(mergeWithMapper.name()); Mapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
if (mergeIntoMapper == null) { if (mergeIntoMapper == null) {
// no mapping, simply add it if not simulating // no mapping, simply add it if not simulating
if (!mergeResult.simulate()) { if (!mergeResult.simulate()) {
mappersToPut.add(mergeWithMapper); mappersToPut.add(mergeWithMapper);
mergeWithMapper.traverse(newFieldMappers); MapperUtils.collect(mergeWithMapper, newObjectMappers, newFieldMappers);
mergeWithMapper.traverse(newObjectMappers);
} }
} else { } else {
mergeIntoMapper.merge(mergeWithMapper, mergeResult); mergeIntoMapper.merge(mergeWithMapper, mergeResult);
} }
} }
if (!newFieldMappers.mappers.isEmpty()) { if (!newFieldMappers.isEmpty()) {
mergeResult.addFieldMappers(newFieldMappers.mappers); mergeResult.addFieldMappers(newFieldMappers);
} }
if (!newObjectMappers.mappers.isEmpty()) { if (!newObjectMappers.isEmpty()) {
mergeResult.addObjectMappers(newObjectMappers.mappers); mergeResult.addObjectMappers(newObjectMappers);
} }
// add the mappers only after the administration have been done, so it will not be visible to parser (which first try to read with no lock) // add the mappers only after the administration have been done, so it will not be visible to parser (which first try to read with no lock)
for (Mapper mapper : mappersToPut) { for (Mapper mapper : mappersToPut) {

View File

@ -89,17 +89,9 @@ public class BooleanFieldMapperTests extends ElasticsearchSingleNodeTest {
.endObject().endObject().string(); .endObject().endObject().string();
DocumentMapper defaultMapper = parser.parse(mapping); DocumentMapper defaultMapper = parser.parse(mapping);
final FieldMapper<?>[] mapper = new BooleanFieldMapper[1]; FieldMapper<?> mapper = defaultMapper.mappers().getMapper("field");
defaultMapper.root().traverse(new FieldMapperListener() {
@Override
public void fieldMapper(FieldMapper<?> fieldMapper) {
if (fieldMapper.name().equals("field")) {
mapper[0] = fieldMapper;
}
}
});
XContentBuilder builder = XContentFactory.jsonBuilder().startObject(); XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
mapper[0].toXContent(builder, ToXContent.EMPTY_PARAMS); mapper.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject(); builder.endObject();
assertEquals("{\"field\":{\"type\":\"boolean\"}}", builder.string()); assertEquals("{\"field\":{\"type\":\"boolean\"}}", builder.string());
@ -113,16 +105,9 @@ public class BooleanFieldMapperTests extends ElasticsearchSingleNodeTest {
.endObject().endObject().string(); .endObject().endObject().string();
defaultMapper = parser.parse(mapping); defaultMapper = parser.parse(mapping);
defaultMapper.root().traverse(new FieldMapperListener() { mapper = defaultMapper.mappers().getMapper("field");
@Override
public void fieldMapper(FieldMapper<?> fieldMapper) {
if (fieldMapper.name().equals("field")) {
mapper[0] = fieldMapper;
}
}
});
builder = XContentFactory.jsonBuilder().startObject(); builder = XContentFactory.jsonBuilder().startObject();
mapper[0].toXContent(builder, ToXContent.EMPTY_PARAMS); mapper.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject(); builder.endObject();
assertEquals("{\"field\":{\"type\":\"boolean\",\"doc_values\":false,\"null_value\":true}}", builder.string()); assertEquals("{\"field\":{\"type\":\"boolean\",\"doc_values\":false,\"null_value\":true}}", builder.string());
} }

View File

@ -19,6 +19,8 @@
package org.elasticsearch.index.mapper.externalvalues; package org.elasticsearch.index.mapper.externalvalues;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.spatial4j.core.shape.Point; import com.spatial4j.core.shape.Point;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FieldType;
@ -221,16 +223,8 @@ public class ExternalMapper extends AbstractFieldMapper<Object> {
} }
@Override @Override
public void traverse(FieldMapperListener fieldMapperListener) { public Iterator<Mapper> iterator() {
binMapper.traverse(fieldMapperListener); return Iterators.concat(super.iterator(), Lists.newArrayList(binMapper, boolMapper, pointMapper, shapeMapper, stringMapper).iterator());
boolMapper.traverse(fieldMapperListener);
pointMapper.traverse(fieldMapperListener);
shapeMapper.traverse(fieldMapperListener);
stringMapper.traverse(fieldMapperListener);
}
@Override
public void traverse(ObjectMapperListener objectMapperListener) {
} }
@Override @Override

View File

@ -25,6 +25,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.mapper.*; import org.elasticsearch.index.mapper.*;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
public class ExternalRootMapper implements RootMapper { public class ExternalRootMapper implements RootMapper {
@ -46,11 +48,8 @@ public class ExternalRootMapper implements RootMapper {
} }
@Override @Override
public void traverse(FieldMapperListener fieldMapperListener) { public Iterator<Mapper> iterator() {
} return Collections.emptyIterator();
@Override
public void traverse(ObjectMapperListener objectMapperListener) {
} }
@Override @Override