diff --git a/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java b/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java index b415ab3f2e14b..7ee03aec31287 100644 --- a/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java +++ b/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java @@ -737,6 +737,11 @@ protected String parseSourceValue(Object value, String format) { if (format != null) { throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats."); } - return value.toString(); + + String keywordValue = value.toString(); + if (keywordValue.length() > ignoreAbove) { + return null; + } + return keywordValue; } } diff --git a/plugins/analysis-icu/src/test/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapperTests.java b/plugins/analysis-icu/src/test/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapperTests.java index 1f69424a06829..1784a74d11f35 100644 --- a/plugins/analysis-icu/src/test/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapperTests.java +++ b/plugins/analysis-icu/src/test/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapperTests.java @@ -494,5 +494,12 @@ public void testParseSourceValue() { assertEquals("value", mapper.parseSourceValue("value", null)); assertEquals("42", mapper.parseSourceValue(42L, null)); assertEquals("true", mapper.parseSourceValue(true, null)); + + ICUCollationKeywordFieldMapper ignoreAboveMapper = new ICUCollationKeywordFieldMapper.Builder("field") + .ignoreAbove(4) + .build(context); + assertNull(ignoreAboveMapper.parseSourceValue("value", null)); + assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null)); + assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null)); } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index a2f3fa6634be8..c2dfa86819126 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -298,7 +298,9 @@ public List lookupValues(SourceLookup lookup, @Nullable String format) { List sourceValues = sourceValue instanceof List ? (List) sourceValue : List.of(sourceValue); for (Object value : sourceValues) { Object parsedValue = parseSourceValue(value, format); - values.add(parsedValue); + if (parsedValue != null) { + values.add(parsedValue); + } } } return values; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java index c3b16c0857f63..239cb88e1b92d 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java @@ -227,14 +227,6 @@ public Mapper.Builder parse(String name, Map node, ParserCont } } - @Override - protected String parseSourceValue(Object value, String format) { - if (format != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats."); - } - return value.toString(); - } - public static final class KeywordFieldType extends StringFieldType { boolean hasNorms; @@ -405,6 +397,20 @@ protected void parseCreateField(ParseContext context) throws IOException { context.doc().add(new SortedSetDocValuesField(fieldType().name(), binaryValue)); } } + + @Override + protected String parseSourceValue(Object value, String format) { + if (format != null) { + throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats."); + } + + String keywordValue = value.toString(); + if (keywordValue.length() > ignoreAbove) { + return null; + } + return keywordValue; + } + @Override protected String contentType() { return CONTENT_TYPE; diff --git a/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldMapperTests.java index 8fd60b1aa41ea..74bf554ff2b44 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldMapperTests.java @@ -633,13 +633,20 @@ public void testMeta() throws Exception { public void testParseSourceValue() { Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build(); Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath()); - KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context); + KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context); assertEquals("value", mapper.parseSourceValue("value", null)); assertEquals("42", mapper.parseSourceValue(42L, null)); assertEquals("true", mapper.parseSourceValue(true, null)); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> mapper.parseSourceValue(true, "format")); assertEquals("Field [field] of type [keyword] doesn't support formats.", e.getMessage()); + + KeywordFieldMapper ignoreAboveMapper = new KeywordFieldMapper.Builder("field") + .ignoreAbove(4) + .build(context); + assertNull(ignoreAboveMapper.parseSourceValue("value", null)); + assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null)); + assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null)); } } diff --git a/server/src/test/java/org/elasticsearch/search/fetch/subphase/FieldValueRetrieverTests.java b/server/src/test/java/org/elasticsearch/search/fetch/subphase/FieldValueRetrieverTests.java index a132be77fc593..8b043fd506f33 100644 --- a/server/src/test/java/org/elasticsearch/search/fetch/subphase/FieldValueRetrieverTests.java +++ b/server/src/test/java/org/elasticsearch/search/fetch/subphase/FieldValueRetrieverTests.java @@ -178,6 +178,33 @@ public void testDateFormat() throws IOException { assertThat(dateField.getValue(), equalTo("1990/12/29")); } + public void testIgnoreAbove() throws IOException { + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject() + .startObject("properties") + .startObject("field") + .field("type", "keyword") + .field("ignore_above", 20) + .endObject() + .endObject() + .endObject(); + + IndexService indexService = createIndex("index", Settings.EMPTY, mapping); + MapperService mapperService = indexService.mapperService(); + + XContentBuilder source = XContentFactory.jsonBuilder().startObject() + .array("field", "value", "other_value", "really_really_long_value") + .endObject(); + Map fields = retrieveFields(mapperService, source, "field"); + DocumentField field = fields.get("field"); + assertThat(field.getValues().size(), equalTo(2)); + + source = XContentFactory.jsonBuilder().startObject() + .array("field", "really_really_long_value") + .endObject(); + fields = retrieveFields(mapperService, source, "field"); + assertFalse(fields.containsKey("field")); + } + public void testFieldAliases() throws IOException { XContentBuilder mapping = XContentFactory.jsonBuilder().startObject() .startObject("properties") diff --git a/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java b/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java index 5e111dcd93ca7..01ff1be1de5ed 100644 --- a/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java +++ b/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java @@ -953,7 +953,12 @@ protected String parseSourceValue(Object value, String format) { if (format != null) { throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats."); } - return value.toString(); + + String keywordValue = value.toString(); + if (keywordValue.length() > ignoreAbove) { + return null; + } + return keywordValue; } void createFields(String value, Document parseDoc, Listfields) throws IOException { diff --git a/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapperTests.java b/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapperTests.java index 0942a93e67c12..a3176576c97ec 100644 --- a/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapperTests.java +++ b/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapperTests.java @@ -774,6 +774,23 @@ protected String convertToRandomRegex(String randomValue) { return result.toString(); } + public void testParseSourceValue() { + Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build(); + Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath()); + + WildcardFieldMapper mapper = new WildcardFieldMapper.Builder("field").build(context); + assertEquals("value", mapper.parseSourceValue("value", null)); + assertEquals("42", mapper.parseSourceValue(42L, null)); + assertEquals("true", mapper.parseSourceValue(true, null)); + + WildcardFieldMapper ignoreAboveMapper = new WildcardFieldMapper.Builder("field") + .ignoreAbove(4) + .build(context); + assertNull(ignoreAboveMapper.parseSourceValue("value", null)); + assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null)); + assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null)); + } + protected MappedFieldType provideMappedFieldType(String name) { if (name.equals(WILDCARD_FIELD_NAME)) { return wildcardFieldType.fieldType();