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:
parent
e83eb49a80
commit
766c787737
|
@ -136,7 +136,7 @@ public class XContentMapValues {
|
||||||
|
|
||||||
public static Map<String, Object> filter(Map<String, Object> map, String[] includes, String[] excludes) {
|
public static Map<String, Object> filter(Map<String, Object> map, String[] includes, String[] excludes) {
|
||||||
Map<String, Object> result = Maps.newHashMap();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,6 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
|
||||||
FIELD_TYPE.freeze();
|
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> {
|
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 format = Defaults.FORMAT;
|
||||||
|
|
||||||
private String[] includes = Defaults.INCLUDES;
|
private String[] includes = null;
|
||||||
private String[] excludes = Defaults.EXCLUDES;
|
private String[] excludes = null;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME);
|
super(Defaults.NAME);
|
||||||
|
@ -192,7 +190,7 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
|
||||||
private XContentType formatContentType;
|
private XContentType formatContentType;
|
||||||
|
|
||||||
public SourceFieldMapper() {
|
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,
|
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() {
|
public String[] excludes() {
|
||||||
return this.excludes;
|
return this.excludes != null ? this.excludes : Strings.EMPTY_ARRAY;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] includes() {
|
public String[] includes() {
|
||||||
return this.includes;
|
return this.includes != null ? this.includes : Strings.EMPTY_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -267,7 +265,7 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
|
||||||
}
|
}
|
||||||
BytesReference source = context.source();
|
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) {
|
if (filtered) {
|
||||||
// we don't update the context source if we filter, we want to keep it as is...
|
// 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
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
// all are defaults, no need to write it at all
|
// 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;
|
return builder;
|
||||||
}
|
}
|
||||||
builder.startObject(contentType());
|
builder.startObject(contentType());
|
||||||
|
@ -384,10 +382,10 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
|
||||||
if (compressThreshold != -1) {
|
if (compressThreshold != -1) {
|
||||||
builder.field("compress_threshold", new ByteSizeValue(compressThreshold).toString());
|
builder.field("compress_threshold", new ByteSizeValue(compressThreshold).toString());
|
||||||
}
|
}
|
||||||
if (includes.length > 0) {
|
if (includes != null) {
|
||||||
builder.field("includes", includes);
|
builder.field("includes", includes);
|
||||||
}
|
}
|
||||||
if (excludes.length > 0) {
|
if (excludes != null) {
|
||||||
builder.field("excludes", excludes);
|
builder.field("excludes", excludes);
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
|
@ -121,7 +121,9 @@ public class UpdateMappingTests extends AbstractSharedClusterTest {
|
||||||
public void updateIncludeExclude() throws Exception {
|
public void updateIncludeExclude() throws Exception {
|
||||||
createIndexMapped("test", "type", "normal", "long", "exclude", "long", "include", "long");
|
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()
|
index("test", "type", "1", JsonXContent.contentBuilder().startObject()
|
||||||
.field("normal", 1).field("exclude", 1).field("include", 1)
|
.field("normal", 1).field("exclude", 1).field("include", 1)
|
||||||
.endObject()
|
.endObject()
|
||||||
|
@ -139,18 +141,27 @@ public class UpdateMappingTests extends AbstractSharedClusterTest {
|
||||||
|
|
||||||
assertTrue(putResponse.isAcknowledged());
|
assertTrue(putResponse.isAcknowledged());
|
||||||
|
|
||||||
logger.info("Index doc 2");
|
// changed mapping doesn't affect indexed documents (checking backward compatibility)
|
||||||
index("test", "type", "2", JsonXContent.contentBuilder().startObject()
|
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)
|
.field("normal", 2).field("exclude", 1).field("include", 2)
|
||||||
.endObject()
|
.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(), hasKey("normal"));
|
||||||
assertThat(getResponse.getSource(), not(hasKey("exclude")));
|
assertThat(getResponse.getSource(), not(hasKey("exclude")));
|
||||||
assertThat(getResponse.getSource(), hasKey("include"));
|
assertThat(getResponse.getSource(), hasKey("include"));
|
||||||
|
|
||||||
|
|
||||||
|
logger.info("Changing mapping to includes");
|
||||||
putResponse = client().admin().indices().preparePutMapping("test").setType("type").setSource(
|
putResponse = client().admin().indices().preparePutMapping("test").setType("type").setSource(
|
||||||
JsonXContent.contentBuilder().startObject().startObject("type")
|
JsonXContent.contentBuilder().startObject().startObject("type")
|
||||||
.startObject("_source")
|
.startObject("_source")
|
||||||
|
@ -163,19 +174,43 @@ public class UpdateMappingTests extends AbstractSharedClusterTest {
|
||||||
GetMappingsResponse getMappingsResponse = client().admin().indices().prepareGetMappings("test").get();
|
GetMappingsResponse getMappingsResponse = client().admin().indices().prepareGetMappings("test").get();
|
||||||
MappingMetaData typeMapping = getMappingsResponse.getMappings().get("test").get("type");
|
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"), 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)
|
.field("normal", 3).field("exclude", 3).field("include", 3)
|
||||||
.endObject()
|
.endObject()
|
||||||
);
|
);
|
||||||
|
|
||||||
getResponse = get("test", "type", "3");
|
getResponse = get("test", "type", "1");
|
||||||
assertThat(getResponse.getSource(), not(hasKey("normal")));
|
assertThat(getResponse.getSource(), not(hasKey("normal")));
|
||||||
assertThat(getResponse.getSource(), not(hasKey("exclude")));
|
assertThat(getResponse.getSource(), not(hasKey("exclude")));
|
||||||
assertThat(getResponse.getSource(), hasKey("include"));
|
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")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
Loading…
Reference in New Issue