Ensure parameters are updated when merging flattened mappings. (#48971) (#49014)

This PR makes the following two fixes around updating flattened fields:

* Make sure that the new value for ignore_above is immediately taken into
  affect. Previously we recorded the new value but did not use it when parsing
  documents.
* Allow depth_limit to be updated dynamically. It seems plausible that a user
  might want to tweak this setting as they encounter more data.
This commit is contained in:
Julie Tibshirani 2019-11-12 21:50:39 -05:00 committed by GitHub
parent 5eb37c29fe
commit 37fa3fb4ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 9 deletions

View File

@ -140,7 +140,8 @@ The following mapping parameters are accepted:
The maximum allowed depth of the flattened object field, in terms of nested
inner objects. If a flattened object field exceeds this limit, then an
error will be thrown. Defaults to `20`.
error will be thrown. Defaults to `20`. Note that `depth_limit` can be
updated dynamically through the <<indices-put-mapping, put mapping>> API.
<<doc-values,`doc_values`>>::

View File

@ -525,7 +525,7 @@ public final class FlatObjectFieldMapper extends DynamicKeyFieldMapper {
}
}
private final FlatObjectFieldParser fieldParser;
private FlatObjectFieldParser fieldParser;
private int depthLimit;
private int ignoreAbove;
@ -552,7 +552,12 @@ public final class FlatObjectFieldMapper extends DynamicKeyFieldMapper {
@Override
protected void doMerge(Mapper mergeWith) {
super.doMerge(mergeWith);
this.ignoreAbove = ((FlatObjectFieldMapper) mergeWith).ignoreAbove;
FlatObjectFieldMapper other = ((FlatObjectFieldMapper) mergeWith);
this.depthLimit = other.depthLimit;
this.ignoreAbove = other.ignoreAbove;
this.fieldParser = new FlatObjectFieldParser(fieldType.name(), keyedFieldName(),
fieldType, depthLimit, ignoreAbove);
}
@Override

View File

@ -316,12 +316,12 @@ public class FlatObjectFieldMapperTests extends ESSingleNodeTestCase {
}
public void testDepthLimit() throws IOException {
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
// First verify the default behavior when depth_limit is not set.
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
.startObject("type")
.startObject("properties")
.startObject("field")
.field("type", "flattened")
.field("depth_limit", 2)
.endObject()
.endObject()
.endObject()
@ -340,8 +340,25 @@ public class FlatObjectFieldMapperTests extends ESSingleNodeTestCase {
.endObject()
.endObject());
mapper.parse(new SourceToParse("test", "type", "1", doc, XContentType.JSON));
// Set a lower value for depth_limit and check that the field is rejected.
String newMapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
.startObject("type")
.startObject("properties")
.startObject("field")
.field("type", "flattened")
.field("depth_limit", 2)
.endObject()
.endObject()
.endObject()
.endObject());
DocumentMapper newMapper = mapper.merge(
parser.parse("type", new CompressedXContent(newMapping)).mapping());
expectThrows(MapperParsingException.class, () ->
mapper.parse(new SourceToParse("test", "type", "1", doc, XContentType.JSON)));
newMapper.parse(new SourceToParse("test", "type", "1", doc, XContentType.JSON)));
}
public void testEagerGlobalOrdinals() throws IOException {
@ -362,12 +379,12 @@ public class FlatObjectFieldMapperTests extends ESSingleNodeTestCase {
}
public void testIgnoreAbove() throws IOException {
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
// First verify the default behavior when ignore_above is not set.
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
.startObject("type")
.startObject("properties")
.startObject("field")
.field("type", "flattened")
.field("ignore_above", 10)
.endObject()
.endObject()
.endObject()
@ -386,7 +403,26 @@ public class FlatObjectFieldMapperTests extends ESSingleNodeTestCase {
ParsedDocument parsedDoc = mapper.parse(new SourceToParse("test", "type", "1", doc, XContentType.JSON));
IndexableField[] fields = parsedDoc.rootDoc().getFields("field");
assertEquals(0, fields.length);
assertEquals(2, fields.length);
// Set a lower value for ignore_above and check that the field is skipped.
String newMapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
.startObject("type")
.startObject("properties")
.startObject("field")
.field("type", "flattened")
.field("ignore_above", "10")
.endObject()
.endObject()
.endObject()
.endObject());
DocumentMapper newMapper = mapper.merge(
parser.parse("type", new CompressedXContent(newMapping)).mapping());
ParsedDocument newParsedDoc = newMapper.parse(new SourceToParse("test", "type", "1", doc, XContentType.JSON));
IndexableField[] newFields = newParsedDoc.rootDoc().getFields("field");
assertEquals(0, newFields.length);
}
public void testNullValues() throws Exception {