Changed the default of SourceFieldMapper's includes & excludes to be null, to support a "not specified" state, which is important now that they are update-able & merge-able

This commit is contained in:
Boaz Leskes 2013-08-18 10:44:12 +02:00
parent e83eb49a80
commit 766c787737
3 changed files with 52 additions and 19 deletions

View File

@ -136,7 +136,7 @@ public class XContentMapValues {
public static Map<String, Object> filter(Map<String, Object> map, String[] includes, String[] excludes) {
Map<String, Object> result = Maps.newHashMap();
filter(map, result, includes, excludes, new StringBuilder());
filter(map, result, includes == null ? Strings.EMPTY_ARRAY : includes, excludes == null ? Strings.EMPTY_ARRAY : excludes, new StringBuilder());
return result;
}

View File

@ -79,8 +79,6 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
FIELD_TYPE.freeze();
}
public static final String[] INCLUDES = Strings.EMPTY_ARRAY;
public static final String[] EXCLUDES = Strings.EMPTY_ARRAY;
}
public static class Builder extends Mapper.Builder<Builder, SourceFieldMapper> {
@ -93,8 +91,8 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
private String format = Defaults.FORMAT;
private String[] includes = Defaults.INCLUDES;
private String[] excludes = Defaults.EXCLUDES;
private String[] includes = null;
private String[] excludes = null;
public Builder() {
super(Defaults.NAME);
@ -192,7 +190,7 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
private XContentType formatContentType;
public SourceFieldMapper() {
this(Defaults.NAME, Defaults.ENABLED, Defaults.FORMAT, null, -1, Defaults.INCLUDES, Defaults.EXCLUDES);
this(Defaults.NAME, Defaults.ENABLED, Defaults.FORMAT, null, -1, null, null);
}
protected SourceFieldMapper(String name, boolean enabled, String format, Boolean compress, long compressThreshold,
@ -213,12 +211,12 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
}
public String[] excludes() {
return this.excludes;
return this.excludes != null ? this.excludes : Strings.EMPTY_ARRAY;
}
public String[] includes() {
return this.includes;
return this.includes != null ? this.includes : Strings.EMPTY_ARRAY;
}
@Override
@ -267,7 +265,7 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
}
BytesReference source = context.source();
boolean filtered = includes.length > 0 || excludes.length > 0;
boolean filtered = (includes != null && includes.length > 0) || (excludes != null && excludes.length > 0);
if (filtered) {
// we don't update the context source if we filter, we want to keep it as is...
@ -368,7 +366,7 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
// all are defaults, no need to write it at all
if (enabled == Defaults.ENABLED && compress == null && compressThreshold == -1 && includes.length == 0 && excludes.length == 0) {
if (enabled == Defaults.ENABLED && compress == null && compressThreshold == -1 && includes == null && excludes == null) {
return builder;
}
builder.startObject(contentType());
@ -384,10 +382,10 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
if (compressThreshold != -1) {
builder.field("compress_threshold", new ByteSizeValue(compressThreshold).toString());
}
if (includes.length > 0) {
if (includes != null) {
builder.field("includes", includes);
}
if (excludes.length > 0) {
if (excludes != null) {
builder.field("excludes", excludes);
}
builder.endObject();

View File

@ -121,7 +121,9 @@ public class UpdateMappingTests extends AbstractSharedClusterTest {
public void updateIncludeExclude() throws Exception {
createIndexMapped("test", "type", "normal", "long", "exclude", "long", "include", "long");
logger.info("Index doc 1");
ensureGreen(); // make sure that replicas are initialized so the refresh command will work them too
logger.info("Index doc");
index("test", "type", "1", JsonXContent.contentBuilder().startObject()
.field("normal", 1).field("exclude", 1).field("include", 1)
.endObject()
@ -139,18 +141,27 @@ public class UpdateMappingTests extends AbstractSharedClusterTest {
assertTrue(putResponse.isAcknowledged());
logger.info("Index doc 2");
index("test", "type", "2", JsonXContent.contentBuilder().startObject()
// changed mapping doesn't affect indexed documents (checking backward compatibility)
GetResponse getResponse = client().prepareGet("test", "type", "1").setRealtime(false).get();
assertThat(getResponse.getSource(), hasKey("normal"));
assertThat(getResponse.getSource(), hasKey("exclude"));
assertThat(getResponse.getSource(), hasKey("include"));
logger.info("Index doc again");
index("test", "type", "1", JsonXContent.contentBuilder().startObject()
.field("normal", 2).field("exclude", 1).field("include", 2)
.endObject()
);
GetResponse getResponse = get("test", "type", "2");
// but do affect newly indexed docs
getResponse = get("test", "type", "1");
assertThat(getResponse.getSource(), hasKey("normal"));
assertThat(getResponse.getSource(), not(hasKey("exclude")));
assertThat(getResponse.getSource(), hasKey("include"));
logger.info("Changing mapping to includes");
putResponse = client().admin().indices().preparePutMapping("test").setType("type").setSource(
JsonXContent.contentBuilder().startObject().startObject("type")
.startObject("_source")
@ -163,19 +174,43 @@ public class UpdateMappingTests extends AbstractSharedClusterTest {
GetMappingsResponse getMappingsResponse = client().admin().indices().prepareGetMappings("test").get();
MappingMetaData typeMapping = getMappingsResponse.getMappings().get("test").get("type");
assertThat((Map<String, Object>) typeMapping.getSourceAsMap().get("_source"), hasKey("includes"));
assertThat((Map<String, Object>) typeMapping.getSourceAsMap().get("_source"), not(hasKey("excludes")));
ArrayList<String> includes = (ArrayList<String>) ((Map<String, Object>) typeMapping.getSourceAsMap().get("_source")).get("includes");
assertThat(includes, contains("include"));
assertThat((Map<String, Object>) typeMapping.getSourceAsMap().get("_source"), hasKey("excludes"));
assertThat((ArrayList<String>) ((Map<String, Object>) typeMapping.getSourceAsMap().get("_source")).get("excludes"), emptyIterable());
index("test", "type", "3", JsonXContent.contentBuilder().startObject()
logger.info("Indexing doc yet again");
index("test", "type", "1", JsonXContent.contentBuilder().startObject()
.field("normal", 3).field("exclude", 3).field("include", 3)
.endObject()
);
getResponse = get("test", "type", "3");
getResponse = get("test", "type", "1");
assertThat(getResponse.getSource(), not(hasKey("normal")));
assertThat(getResponse.getSource(), not(hasKey("exclude")));
assertThat(getResponse.getSource(), hasKey("include"));
logger.info("Adding excludes, but keep includes");
putResponse = client().admin().indices().preparePutMapping("test").setType("type").setSource(
JsonXContent.contentBuilder().startObject().startObject("type")
.startObject("_source")
.startArray("excludes").value("*.excludes").endArray()
.endObject().endObject()
).get();
assertTrue(putResponse.isAcknowledged());
getMappingsResponse = client().admin().indices().prepareGetMappings("test").get();
typeMapping = getMappingsResponse.getMappings().get("test").get("type");
assertThat((Map<String, Object>) typeMapping.getSourceAsMap().get("_source"), hasKey("includes"));
includes = (ArrayList<String>) ((Map<String, Object>) typeMapping.getSourceAsMap().get("_source")).get("includes");
assertThat(includes, contains("include"));
assertThat((Map<String, Object>) typeMapping.getSourceAsMap().get("_source"), hasKey("excludes"));
ArrayList<String> excludes = (ArrayList<String>) ((Map<String, Object>) typeMapping.getSourceAsMap().get("_source")).get("excludes");
assertThat(excludes, contains("*.excludes"));
}
@SuppressWarnings("unchecked")