Make merging mappings smarter, closes #253.

This commit is contained in:
kimchy 2010-07-14 07:32:17 +03:00
parent 892dadca59
commit 234455530a
11 changed files with 124 additions and 20 deletions

View File

@ -36,6 +36,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericDateAnalyzer;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.Map;
@ -104,7 +105,7 @@ public class XContentDateFieldMapper extends XContentNumberFieldMapper<Long> {
private final FormatDateTimeFormatter dateTimeFormatter;
private final String nullValue;
private String nullValue;
protected XContentDateFieldMapper(Names names, FormatDateTimeFormatter dateTimeFormatter, int precisionStep,
Field.Index index, Field.Store store,
@ -213,6 +214,13 @@ public class XContentDateFieldMapper extends XContentNumberFieldMapper<Long> {
return CONTENT_TYPE;
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.nullValue = ((XContentDateFieldMapper) mergeWith).nullValue;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
builder.field("format", dateTimeFormatter.format());

View File

@ -33,6 +33,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericDoubleAnalyzer;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.Map;
@ -90,9 +91,9 @@ public class XContentDoubleFieldMapper extends XContentNumberFieldMapper<Double>
}
private final Double nullValue;
private Double nullValue;
private final String nullValueAsString;
private String nullValueAsString;
protected XContentDoubleFieldMapper(Names names, int precisionStep,
Field.Index index, Field.Store store,
@ -195,6 +196,14 @@ public class XContentDoubleFieldMapper extends XContentNumberFieldMapper<Double>
return CONTENT_TYPE;
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.nullValue = ((XContentDoubleFieldMapper) mergeWith).nullValue;
this.nullValueAsString = ((XContentDoubleFieldMapper) mergeWith).nullValueAsString;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
if (nullValue != null) {

View File

@ -193,11 +193,11 @@ public abstract class XContentFieldMapper<T> implements FieldMapper<T>, XContent
protected final Field.TermVector termVector;
protected final float boost;
protected float boost;
protected final boolean omitNorms;
protected boolean omitNorms;
protected final boolean omitTermFreqAndPositions;
protected boolean omitTermFreqAndPositions;
protected final NamedAnalyzer indexAnalyzer;
@ -341,7 +341,39 @@ public abstract class XContentFieldMapper<T> implements FieldMapper<T>, XContent
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
mergeContext.addConflict("Mapper [" + names.fullName() + "] exists, can't merge");
if (!this.getClass().equals(mergeWith.getClass())) {
mergeContext.addConflict("mapper [" + names.fullName() + "] of different type");
}
XContentFieldMapper fieldMergeWith = (XContentFieldMapper) mergeWith;
if (!this.index.equals(fieldMergeWith.index)) {
mergeContext.addConflict("mapper [" + names.fullName() + "] has different index values");
}
if (!this.store.equals(fieldMergeWith.store)) {
mergeContext.addConflict("mapper [" + names.fullName() + "] has different store values");
}
if (!this.termVector.equals(fieldMergeWith.termVector)) {
mergeContext.addConflict("mapper [" + names.fullName() + "] has different term_vector values");
}
if (this.indexAnalyzer == null) {
if (fieldMergeWith.indexAnalyzer != null) {
mergeContext.addConflict("mapper [" + names.fullName() + "] has different index_analyzer");
}
} else if (!this.indexAnalyzer.name().equals(fieldMergeWith.indexAnalyzer.name())) {
mergeContext.addConflict("mapper [" + names.fullName() + "] has different index_analyzer");
}
if (this.searchAnalyzer == null) {
if (fieldMergeWith.searchAnalyzer != null) {
mergeContext.addConflict("mapper [" + names.fullName() + "] has different search_analyzer");
}
} else if (!this.searchAnalyzer.name().equals(fieldMergeWith.searchAnalyzer.name())) {
mergeContext.addConflict("mapper [" + names.fullName() + "] has different search_analyzer");
}
if (!mergeContext.mergeFlags().simulate()) {
// apply changeable values
this.boost = fieldMergeWith.boost;
this.omitNorms = fieldMergeWith.omitNorms;
this.omitTermFreqAndPositions = fieldMergeWith.omitTermFreqAndPositions;
}
}
@Override public FieldData.Type fieldDataType() {

View File

@ -34,6 +34,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericFloatAnalyzer;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.Map;
@ -90,9 +91,9 @@ public class XContentFloatFieldMapper extends XContentNumberFieldMapper<Float> {
}
}
private final Float nullValue;
private Float nullValue;
private final String nullValueAsString;
private String nullValueAsString;
protected XContentFloatFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
@ -194,6 +195,15 @@ public class XContentFloatFieldMapper extends XContentNumberFieldMapper<Float> {
return CONTENT_TYPE;
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.nullValue = ((XContentFloatFieldMapper) mergeWith).nullValue;
this.nullValueAsString = ((XContentFloatFieldMapper) mergeWith).nullValueAsString;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
if (nullValue != null) {

View File

@ -34,6 +34,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.Map;
@ -90,9 +91,9 @@ public class XContentIntegerFieldMapper extends XContentNumberFieldMapper<Intege
}
}
private final Integer nullValue;
private Integer nullValue;
private final String nullValueAsString;
private String nullValueAsString;
protected XContentIntegerFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
@ -194,6 +195,14 @@ public class XContentIntegerFieldMapper extends XContentNumberFieldMapper<Intege
return CONTENT_TYPE;
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.nullValue = ((XContentIntegerFieldMapper) mergeWith).nullValue;
this.nullValueAsString = ((XContentIntegerFieldMapper) mergeWith).nullValueAsString;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
if (nullValue != null) {

View File

@ -34,6 +34,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericLongAnalyzer;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.Map;
@ -90,9 +91,9 @@ public class XContentLongFieldMapper extends XContentNumberFieldMapper<Long> {
}
}
private final Long nullValue;
private Long nullValue;
private final String nullValueAsString;
private String nullValueAsString;
protected XContentLongFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
@ -194,6 +195,14 @@ public class XContentLongFieldMapper extends XContentNumberFieldMapper<Long> {
return CONTENT_TYPE;
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.nullValue = ((XContentLongFieldMapper) mergeWith).nullValue;
this.nullValueAsString = ((XContentLongFieldMapper) mergeWith).nullValueAsString;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
if (nullValue != null) {

View File

@ -31,6 +31,7 @@ import org.elasticsearch.common.trove.TIntObjectHashMap;
import org.elasticsearch.common.xcontent.builder.XContentBuilder;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.ArrayDeque;
@ -87,7 +88,7 @@ public abstract class XContentNumberFieldMapper<T extends Number> extends XConte
}
};
protected final int precisionStep;
protected int precisionStep;
protected Boolean includeInAll;
@ -156,6 +157,14 @@ public abstract class XContentNumberFieldMapper<T extends Number> extends XConte
@Override public abstract Object valueFromTerm(String term);
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.precisionStep = ((XContentNumberFieldMapper) mergeWith).precisionStep;
this.includeInAll = ((XContentNumberFieldMapper) mergeWith).includeInAll;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
builder.field("precision_step", precisionStep);

View File

@ -34,6 +34,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.Map;
@ -90,9 +91,9 @@ public class XContentShortFieldMapper extends XContentNumberFieldMapper<Short> {
}
}
private final Short nullValue;
private Short nullValue;
private final String nullValueAsString;
private String nullValueAsString;
protected XContentShortFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
@ -194,6 +195,14 @@ public class XContentShortFieldMapper extends XContentNumberFieldMapper<Short> {
return CONTENT_TYPE;
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.nullValue = ((XContentShortFieldMapper) mergeWith).nullValue;
this.nullValueAsString = ((XContentShortFieldMapper) mergeWith).nullValueAsString;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
if (nullValue != null) {

View File

@ -26,6 +26,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.builder.XContentBuilder;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import java.io.IOException;
import java.util.Map;
@ -89,7 +90,7 @@ public class XContentStringFieldMapper extends XContentFieldMapper<String> imple
}
private final String nullValue;
private String nullValue;
private Boolean includeInAll;
@ -148,6 +149,14 @@ public class XContentStringFieldMapper extends XContentFieldMapper<String> imple
return CONTENT_TYPE;
}
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
super.merge(mergeWith, mergeContext);
if (!mergeContext.mergeFlags().simulate()) {
this.includeInAll = ((XContentStringFieldMapper) mergeWith).includeInAll;
this.nullValue = ((XContentStringFieldMapper) mergeWith).nullValue;
}
}
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
super.doXContentBody(builder);
if (nullValue != null) {

View File

@ -44,13 +44,13 @@ public class Test1MergeMapperTests {
XContentDocumentMapper stage2 = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(stage2Mapping);
DocumentMapper.MergeResult mergeResult = stage1.merge(stage2, mergeFlags().simulate(true));
assertThat(mergeResult.hasConflicts(), equalTo(true));
assertThat(mergeResult.hasConflicts(), equalTo(false));
// since we are simulating, we should not have the age mapping
assertThat(stage1.mappers().smartName("age"), nullValue());
// now merge, don't simulate
mergeResult = stage1.merge(stage2, mergeFlags().simulate(false));
// there is still merge failures
assertThat(mergeResult.hasConflicts(), equalTo(true));
assertThat(mergeResult.hasConflicts(), equalTo(false));
// but we have the age in
assertThat(stage1.mappers().smartName("age"), notNullValue());
}

View File

@ -1,7 +1,7 @@
{
person : {
properties : {
name : {type : "integer"},
name : {type : "string"},
age : {type : "integer"}
}
}