Skip to content

Commit ce1eac5

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 5bab3bf commit ce1eac5

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
@@ -759,6 +759,11 @@ protected String parseSourceValue(Object value, String format) {
759759
if (format != null) {
760760
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
761761
}
762-
return value.toString();
762+
763+
String keywordValue = value.toString();
764+
if (keywordValue.length() > ignoreAbove) {
765+
return null;
766+
}
767+
return keywordValue;
763768
}
764769
}

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
@@ -310,7 +310,9 @@ public List<?> lookupValues(SourceLookup lookup, @Nullable String format) {
310310
List<?> sourceValues = sourceValue instanceof List ? (List<?>) sourceValue : List.of(sourceValue);
311311
for (Object value : sourceValues) {
312312
Object parsedValue = parseSourceValue(value, format);
313-
values.add(parsedValue);
313+
if (parsedValue != null) {
314+
values.add(parsedValue);
315+
}
314316
}
315317
}
316318
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
@@ -216,14 +216,6 @@ public Mapper.Builder<?> parse(String name, Map<String, Object> node, ParserCont
216216
}
217217
}
218218

219-
@Override
220-
protected String parseSourceValue(Object value, String format) {
221-
if (format != null) {
222-
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
223-
}
224-
return value.toString();
225-
}
226-
227219
public static final class KeywordFieldType extends StringFieldType {
228220

229221
boolean hasNorms;
@@ -416,6 +408,20 @@ protected void parseCreateField(ParseContext context) throws IOException {
416408
context.doc().add(new SortedSetDocValuesField(fieldType().name(), binaryValue));
417409
}
418410
}
411+
412+
@Override
413+
protected String parseSourceValue(Object value, String format) {
414+
if (format != null) {
415+
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
416+
}
417+
418+
String keywordValue = value.toString();
419+
if (keywordValue.length() > ignoreAbove) {
420+
return null;
421+
}
422+
return keywordValue;
423+
}
424+
419425
@Override
420426
protected String contentType() {
421427
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
@@ -621,13 +621,20 @@ public void testMeta() throws Exception {
621621
public void testParseSourceValue() {
622622
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build();
623623
Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath());
624-
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
625624

625+
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
626626
assertEquals("value", mapper.parseSourceValue("value", null));
627627
assertEquals("42", mapper.parseSourceValue(42L, null));
628628
assertEquals("true", mapper.parseSourceValue(true, null));
629629

630630
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> mapper.parseSourceValue(true, "format"));
631631
assertEquals("Field [field] of type [keyword] doesn't support formats.", e.getMessage());
632+
633+
KeywordFieldMapper ignoreAboveMapper = new KeywordFieldMapper.Builder("field")
634+
.ignoreAbove(4)
635+
.build(context);
636+
assertNull(ignoreAboveMapper.parseSourceValue("value", null));
637+
assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null));
638+
assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null));
632639
}
633640
}

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
@@ -962,7 +962,12 @@ protected String parseSourceValue(Object value, String format) {
962962
if (format != null) {
963963
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
964964
}
965-
return value.toString();
965+
966+
String keywordValue = value.toString();
967+
if (keywordValue.length() > ignoreAbove) {
968+
return null;
969+
}
970+
return keywordValue;
966971
}
967972

968973
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)