Skip to content

Commit 8131b5e

Browse files
authored
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 4788875 commit 8131b5e

File tree

8 files changed

+148
-72
lines changed

8 files changed

+148
-72
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
@@ -750,6 +750,11 @@ protected String parseSourceValue(Object value, String format) {
750750
if (format != null) {
751751
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
752752
}
753-
return value.toString();
753+
754+
String keywordValue = value.toString();
755+
if (keywordValue.length() > ignoreAbove) {
756+
return null;
757+
}
758+
return keywordValue;
754759
}
755760
}

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
@@ -488,5 +488,12 @@ public void testParseSourceValue() {
488488
assertEquals("value", mapper.parseSourceValue("value", null));
489489
assertEquals("42", mapper.parseSourceValue(42L, null));
490490
assertEquals("true", mapper.parseSourceValue(true, null));
491+
492+
ICUCollationKeywordFieldMapper ignoreAboveMapper = new ICUCollationKeywordFieldMapper.Builder("field")
493+
.ignoreAbove(4)
494+
.build(context);
495+
assertNull(ignoreAboveMapper.parseSourceValue("value", null));
496+
assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null));
497+
assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null));
491498
}
492499
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ public List<?> lookupValues(SourceLookup lookup, @Nullable String format) {
349349
List<?> sourceValues = sourceValue instanceof List ? (List<?>) sourceValue : List.of(sourceValue);
350350
for (Object value : sourceValues) {
351351
Object parsedValue = parseSourceValue(value, format);
352-
values.add(parsedValue);
352+
if (parsedValue != null) {
353+
values.add(parsedValue);
354+
}
353355
}
354356
}
355357
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
@@ -186,14 +186,6 @@ public Mapper.Builder<?> parse(String name, Map<String, Object> node, ParserCont
186186
}
187187
}
188188

189-
@Override
190-
protected String parseSourceValue(Object value, String format) {
191-
if (format != null) {
192-
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
193-
}
194-
return value.toString();
195-
}
196-
197189
public static final class KeywordFieldType extends StringFieldType {
198190

199191
private NamedAnalyzer normalizer = null;
@@ -382,6 +374,20 @@ protected void parseCreateField(ParseContext context) throws IOException {
382374
context.doc().add(new SortedSetDocValuesField(fieldType().name(), binaryValue));
383375
}
384376
}
377+
378+
@Override
379+
protected String parseSourceValue(Object value, String format) {
380+
if (format != null) {
381+
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
382+
}
383+
384+
String keywordValue = value.toString();
385+
if (keywordValue.length() > ignoreAbove) {
386+
return null;
387+
}
388+
return keywordValue;
389+
}
390+
385391
@Override
386392
protected String contentType() {
387393
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
@@ -604,13 +604,20 @@ public void testMeta() throws Exception {
604604
public void testParseSourceValue() {
605605
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build();
606606
Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath());
607-
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
608607

608+
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
609609
assertEquals("value", mapper.parseSourceValue("value", null));
610610
assertEquals("42", mapper.parseSourceValue(42L, null));
611611
assertEquals("true", mapper.parseSourceValue(true, null));
612612

613613
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> mapper.parseSourceValue(true, "format"));
614614
assertEquals("Field [field] of type [keyword] doesn't support formats.", e.getMessage());
615+
616+
KeywordFieldMapper ignoreAboveMapper = new KeywordFieldMapper.Builder("field")
617+
.ignoreAbove(4)
618+
.build(context);
619+
assertNull(ignoreAboveMapper.parseSourceValue("value", null));
620+
assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null));
621+
assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null));
615622
}
616623
}

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
@@ -893,7 +893,12 @@ protected String parseSourceValue(Object value, String format) {
893893
if (format != null) {
894894
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
895895
}
896-
return value.toString();
896+
897+
String keywordValue = value.toString();
898+
if (keywordValue.length() > ignoreAbove) {
899+
return null;
900+
}
901+
return keywordValue;
897902
}
898903

899904
// For internal use by Lucene only - used to define ngram index

0 commit comments

Comments
 (0)