Skip to content

Commit ae8da97

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 0e0cc69 commit ae8da97

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
@@ -737,6 +737,11 @@ protected String parseSourceValue(Object value, String format) {
737737
if (format != null) {
738738
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
739739
}
740-
return value.toString();
740+
741+
String keywordValue = value.toString();
742+
if (keywordValue.length() > ignoreAbove) {
743+
return null;
744+
}
745+
return keywordValue;
741746
}
742747
}

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
@@ -298,7 +298,9 @@ public List<?> lookupValues(SourceLookup lookup, @Nullable String format) {
298298
List<?> sourceValues = sourceValue instanceof List ? (List<?>) sourceValue : List.of(sourceValue);
299299
for (Object value : sourceValues) {
300300
Object parsedValue = parseSourceValue(value, format);
301-
values.add(parsedValue);
301+
if (parsedValue != null) {
302+
values.add(parsedValue);
303+
}
302304
}
303305
}
304306
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;
@@ -405,6 +397,20 @@ protected void parseCreateField(ParseContext context) throws IOException {
405397
context.doc().add(new SortedSetDocValuesField(fieldType().name(), binaryValue));
406398
}
407399
}
400+
401+
@Override
402+
protected String parseSourceValue(Object value, String format) {
403+
if (format != null) {
404+
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
405+
}
406+
407+
String keywordValue = value.toString();
408+
if (keywordValue.length() > ignoreAbove) {
409+
return null;
410+
}
411+
return keywordValue;
412+
}
413+
408414
@Override
409415
protected String contentType() {
410416
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
@@ -633,13 +633,20 @@ public void testMeta() throws Exception {
633633
public void testParseSourceValue() {
634634
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build();
635635
Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath());
636-
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
637636

637+
KeywordFieldMapper mapper = new KeywordFieldMapper.Builder("field").build(context);
638638
assertEquals("value", mapper.parseSourceValue("value", null));
639639
assertEquals("42", mapper.parseSourceValue(42L, null));
640640
assertEquals("true", mapper.parseSourceValue(true, null));
641641

642642
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> mapper.parseSourceValue(true, "format"));
643643
assertEquals("Field [field] of type [keyword] doesn't support formats.", e.getMessage());
644+
645+
KeywordFieldMapper ignoreAboveMapper = new KeywordFieldMapper.Builder("field")
646+
.ignoreAbove(4)
647+
.build(context);
648+
assertNull(ignoreAboveMapper.parseSourceValue("value", null));
649+
assertEquals("42", ignoreAboveMapper.parseSourceValue(42L, null));
650+
assertEquals("true", ignoreAboveMapper.parseSourceValue(true, null));
644651
}
645652
}

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
@@ -953,7 +953,12 @@ protected String parseSourceValue(Object value, String format) {
953953
if (format != null) {
954954
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
955955
}
956-
return value.toString();
956+
957+
String keywordValue = value.toString();
958+
if (keywordValue.length() > ignoreAbove) {
959+
return null;
960+
}
961+
return keywordValue;
957962
}
958963

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