Skip to content

Commit aa38677

Browse files
committed
Respect the ignore_above option. (#57307)
For keyword-style fields, if the source value is larger than `ignore_above` then we don't retrieve the field. In particular, the field is treated as if the value didn't exist.
1 parent 6a86fc8 commit aa38677

File tree

8 files changed

+88
-12
lines changed

8 files changed

+88
-12
lines changed

plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,11 @@ protected String parseSourceValue(Object value, String format) {
758758
if (format != null) {
759759
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
760760
}
761-
return value.toString();
761+
762+
String keywordValue = value.toString();
763+
if (keywordValue.length() > ignoreAbove) {
764+
return null;
765+
}
766+
return keywordValue;
762767
}
763768
}

plugins/analysis-icu/src/test/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapperTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,5 +494,12 @@ public void testParseSourceValue() {
494494
assertEquals("value", mapper.parseSourceValue("value", null));
495495
assertEquals("42", mapper.parseSourceValue(42L, null));
496496
assertEquals("true", mapper.parseSourceValue(true, null));
497+
498+
ICUCollationKeywordFieldMapper ignoreAboveMapper = new ICUCollationKeywordFieldMapper.Builder("field")
499+
.ignoreAbove(4)
500+
.build(context);
501+
assertNull(ignoreAboveMapper.parseSourceValue("value", null));
502+
assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null));
503+
assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null));
497504
}
498505
}

server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,9 @@ public List<?> lookupValues(SourceLookup lookup, @Nullable String format) {
297297
List<?> sourceValues = sourceValue instanceof List ? (List<?>) sourceValue : List.of(sourceValue);
298298
for (Object value : sourceValues) {
299299
Object parsedValue = parseSourceValue(value, format);
300-
values.add(parsedValue);
300+
if (parsedValue != null) {
301+
values.add(parsedValue);
302+
}
301303
}
302304
}
303305
return values;

server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,6 @@ public Mapper.Builder<?> parse(String name, Map<String, Object> node, ParserCont
227227
}
228228
}
229229

230-
@Override
231-
protected String parseSourceValue(Object value, String format) {
232-
if (format != null) {
233-
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
234-
}
235-
return value.toString();
236-
}
237-
238230
public static final class KeywordFieldType extends StringFieldType {
239231

240232
boolean hasNorms;
@@ -430,6 +422,20 @@ protected void parseCreateField(ParseContext context) throws IOException {
430422
context.doc().add(new SortedSetDocValuesField(fieldType().name(), binaryValue));
431423
}
432424
}
425+
426+
@Override
427+
protected String parseSourceValue(Object value, String format) {
428+
if (format != null) {
429+
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
430+
}
431+
432+
String keywordValue = value.toString();
433+
if (keywordValue.length() > ignoreAbove) {
434+
return null;
435+
}
436+
return keywordValue;
437+
}
438+
433439
@Override
434440
protected String contentType() {
435441
return CONTENT_TYPE;

server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldMapperTests.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,13 +628,20 @@ public void testMeta() throws Exception {
628628
public void testParseSourceValue() {
629629
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build();
630630
Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath());
631-
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
632631

632+
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
633633
assertEquals("value", mapper.parseSourceValue("value", null));
634634
assertEquals("42", mapper.parseSourceValue(42L, null));
635635
assertEquals("true", mapper.parseSourceValue(true, null));
636636

637637
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> mapper.parseSourceValue(true, "format"));
638638
assertEquals("Field [field] of type [keyword] doesn't support formats.", e.getMessage());
639+
640+
KeywordFieldMapper ignoreAboveMapper = new KeywordFieldMapper.Builder("field")
641+
.ignoreAbove(4)
642+
.build(context);
643+
assertNull(ignoreAboveMapper.parseSourceValue("value", null));
644+
assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null));
645+
assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null));
639646
}
640647
}

server/src/test/java/org/elasticsearch/search/fetch/subphase/FieldValueRetrieverTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,33 @@ public void testDateFormat() throws IOException {
178178
assertThat(dateField.getValue(), equalTo("1990/12/29"));
179179
}
180180

181+
public void testIgnoreAbove() throws IOException {
182+
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject()
183+
.startObject("properties")
184+
.startObject("field")
185+
.field("type", "keyword")
186+
.field("ignore_above", 20)
187+
.endObject()
188+
.endObject()
189+
.endObject();
190+
191+
IndexService indexService = createIndex("index", Settings.EMPTY, mapping);
192+
MapperService mapperService = indexService.mapperService();
193+
194+
XContentBuilder source = XContentFactory.jsonBuilder().startObject()
195+
.array("field", "value", "other_value", "really_really_long_value")
196+
.endObject();
197+
Map<String, DocumentField> fields = retrieveFields(mapperService, source, "field");
198+
DocumentField field = fields.get("field");
199+
assertThat(field.getValues().size(), equalTo(2));
200+
201+
source = XContentFactory.jsonBuilder().startObject()
202+
.array("field", "really_really_long_value")
203+
.endObject();
204+
fields = retrieveFields(mapperService, source, "field");
205+
assertFalse(fields.containsKey("field"));
206+
}
207+
181208
public void testFieldAliases() throws IOException {
182209
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject()
183210
.startObject("properties")

x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,12 @@ protected String parseSourceValue(Object value, String format) {
963963
if (format != null) {
964964
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
965965
}
966-
return value.toString();
966+
967+
String keywordValue = value.toString();
968+
if (keywordValue.length() > ignoreAbove) {
969+
return null;
970+
}
971+
return keywordValue;
967972
}
968973

969974
void createFields(String value, Document parseDoc, List<IndexableField>fields) throws IOException {

x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapperTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,23 @@ protected String convertToRandomRegex(String randomValue) {
774774
return result.toString();
775775
}
776776

777+
public void testParseSourceValue() {
778+
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build();
779+
Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath());
780+
781+
WildcardFieldMapper mapper = new WildcardFieldMapper.Builder("field").build(context);
782+
assertEquals("value", mapper.parseSourceValue("value", null));
783+
assertEquals("42", mapper.parseSourceValue(42L, null));
784+
assertEquals("true", mapper.parseSourceValue(true, null));
785+
786+
WildcardFieldMapper ignoreAboveMapper = new WildcardFieldMapper.Builder("field")
787+
.ignoreAbove(4)
788+
.build(context);
789+
assertNull(ignoreAboveMapper.parseSourceValue("value", null));
790+
assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null));
791+
assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null));
792+
}
793+
777794
protected MappedFieldType provideMappedFieldType(String name) {
778795
if (name.equals(WILDCARD_FIELD_NAME)) {
779796
return wildcardFieldType.fieldType();

0 commit comments

Comments
 (0)