some merge mapping work, tests...

This commit is contained in:
kimchy 2010-02-28 12:28:48 +02:00
parent f51e2cf905
commit c6683d23ef
13 changed files with 134 additions and 19 deletions

View File

@ -111,6 +111,9 @@ public interface DocumentMapper {
public MergeFlags() {
}
/**
* A simulation run, don't perform actual modifications to the mapping.
*/
public boolean simulate() {
return simulate;
}

View File

@ -137,12 +137,18 @@ public interface FieldMapper<T> {
*/
String indexedValue(T value);
/**
* Should the field query {@link #fieldQuery(String)} be used when detecting this
* field in query string.
*/
boolean useFieldQueryWithQueryString();
Query fieldQuery(String value);
Filter fieldFilter(String value);
void merge(FieldMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException;
/**
* Constructs a range query based on the mapper.
*/

View File

@ -27,13 +27,16 @@ import org.codehaus.jackson.JsonToken;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericFloatAnalyzer;
import org.elasticsearch.index.mapper.BoostFieldMapper;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.util.Numbers;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
/**
* @author kimchy (Shay Banon)
* @author kimchy (shay.banon)
*/
public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implements BoostFieldMapper {
@ -179,4 +182,8 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
}
builder.endObject();
}
@Override public void merge(FieldMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
// do nothing here, no merging, but also no exception
}
}

View File

@ -349,7 +349,7 @@ public class JsonDocumentMapper implements DocumentMapper, ToJson {
@Override public synchronized void merge(DocumentMapper mergeWith, MergeFlags mergeFlags) throws MergeMappingException {
JsonDocumentMapper jsonMergeWith = (JsonDocumentMapper) mergeWith;
rootObjectMapper.mergeMapping(jsonMergeWith.rootObjectMapper, mergeFlags);
rootObjectMapper.mergeMapping(this, jsonMergeWith.rootObjectMapper, mergeFlags);
if (!mergeFlags.simulate()) {
// update the source to the merged one
mappingSource = buildSource();

View File

@ -25,8 +25,10 @@ import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.*;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.FieldMapperListener;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.util.json.JsonBuilder;
import org.elasticsearch.util.lucene.search.TermFilter;
@ -319,6 +321,13 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
includeLower, includeUpper);
}
@Override public void merge(FieldMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
if (mergeFlags.ignoreDuplicates()) {
return;
}
throw new MergeMappingException("Mapper [" + names.fullName() + "] exists, can't merge");
}
@Override public int sortType() {
return SortField.STRING;
}

View File

@ -22,9 +22,7 @@ package org.elasticsearch.index.mapper.json;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.elasticsearch.index.mapper.FieldMapperListener;
import org.elasticsearch.index.mapper.IdFieldMapper;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.*;
import org.elasticsearch.util.json.JsonBuilder;
import org.elasticsearch.util.lucene.Lucene;
@ -124,4 +122,8 @@ public class JsonIdFieldMapper extends JsonFieldMapper<String> implements IdFiel
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
// for now, don't output it at all
}
@Override public void merge(FieldMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
// do nothing here, no merging, but also no exception
}
}

View File

@ -337,7 +337,7 @@ public class JsonObjectMapper implements JsonMapper {
}
}
public void mergeMapping(JsonObjectMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
public void mergeMapping(JsonDocumentMapper docMapper, JsonObjectMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
synchronized (mutex) {
for (JsonMapper mapper : mergeWith.mappers.values()) {
if (mapper instanceof JsonObjectMapper) {
@ -347,26 +347,23 @@ public class JsonObjectMapper implements JsonMapper {
if (!(mergeIntoMapper instanceof JsonObjectMapper)) {
throw new MergeMappingException("Can't merge an object mapping [" + mergeWithMapper.name() + "] into a non object mapper");
}
((JsonObjectMapper) mergeIntoMapper).mergeMapping(mergeWithMapper, mergeFlags);
((JsonObjectMapper) mergeIntoMapper).mergeMapping(docMapper, mergeWithMapper, mergeFlags);
} else {
if (!mergeFlags.simulate()) {
putMapper(mergeWithMapper);
}
}
} else {
JsonFieldMapper mergeWithMapper = (JsonFieldMapper) mapper;
JsonFieldMapper mergeIntoMapper = (JsonFieldMapper) mappers.get(mergeWithMapper.name());
// not an object mapper, bail if we have it, otherwise, add
// we might get fancy later on and allow per field mapper merge
if (mappers.containsKey(mapper.name())) {
if (mappers.get(mapper.name()) instanceof InternalMapper) {
// simple ignore internal mappings
} else {
if (!mergeFlags.ignoreDuplicates()) {
throw new MergeMappingException("Mapper [" + mapper.name() + "] exists, can't merge");
}
}
if (mergeIntoMapper != null) {
mergeIntoMapper.merge(mergeWithMapper, mergeFlags);
} else {
if (!mergeFlags.simulate()) {
putMapper(mapper);
putMapper(mergeWithMapper);
docMapper.addFieldMapper(mergeWithMapper);
}
}
}

View File

@ -20,6 +20,9 @@
package org.elasticsearch.index.mapper.json;
import org.apache.lucene.document.*;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.util.json.JsonBuilder;
import org.elasticsearch.util.lucene.Lucene;
@ -131,4 +134,8 @@ public class JsonSourceFieldMapper extends JsonFieldMapper<byte[]> implements So
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
// for now, don't output it at all
}
@Override public void merge(FieldMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
// do nothing here, no merging, but also no exception
}
}

View File

@ -23,6 +23,9 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Term;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.TypeFieldMapper;
import org.elasticsearch.util.json.JsonBuilder;
import org.elasticsearch.util.lucene.Lucene;
@ -108,4 +111,8 @@ public class JsonTypeFieldMapper extends JsonFieldMapper<String> implements Type
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
// for now, don't output it at all
}
@Override public void merge(FieldMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
// do nothing here, no merging, but also no exception
}
}

View File

@ -22,9 +22,7 @@ package org.elasticsearch.index.mapper.json;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Term;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.Uid;
import org.elasticsearch.index.mapper.UidFieldMapper;
import org.elasticsearch.index.mapper.*;
import org.elasticsearch.util.json.JsonBuilder;
import org.elasticsearch.util.lucene.Lucene;
@ -106,4 +104,8 @@ public class JsonUidFieldMapper extends JsonFieldMapper<Uid> implements UidField
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
// for now, don't output it at all
}
@Override public void merge(FieldMapper mergeWith, DocumentMapper.MergeFlags mergeFlags) throws MergeMappingException {
// do nothing here, no merging, but also no exception
}
}

View File

@ -0,0 +1,60 @@
/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search 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.index.mapper.json.merge.test1;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.json.JsonDocumentMapper;
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
import org.testng.annotations.Test;
import static org.elasticsearch.index.mapper.DocumentMapper.MergeFlags.*;
import static org.elasticsearch.util.io.Streams.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
/**
* @author kimchy (shay.banon)
*/
@Test
public class Test1MergeMapperTests {
@Test public void test1Merge() throws Exception {
String stage1Mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/merge/test1/stage1.json");
JsonDocumentMapper stage1 = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(stage1Mapping);
String stage2Mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/merge/test1/stage2.json");
JsonDocumentMapper stage2 = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(stage2Mapping);
try {
stage1.merge(stage2, mergeFlags().simulate(true));
assert false : "can't change field from number to type";
} catch (MergeMappingException e) {
// all is well
}
// now, test with ignore duplicates
stage1.merge(stage2, mergeFlags().ignoreDuplicates(true).simulate(true));
// since we are simulating, we should not have the age mapping
assertThat(stage1.mappers().smartName("age"), nullValue());
// now merge, ignore duplicates and don't simulate
stage1.merge(stage2, mergeFlags().ignoreDuplicates(true).simulate(false));
assertThat(stage1.mappers().smartName("age"), notNullValue());
}
}

View File

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

View File

@ -0,0 +1,8 @@
{
person : {
properties : {
name : {type : "integer"},
age : {type : "integer"}
}
}
}