Skip to content

Commit 521e434

Browse files
ignore_above default to 8191 for logsdb (#113442)
In LogsDB we would like to use a default value of `8191` for the index-level setting `index.mapping.ignore_above`. The value for `ignore_above` is the _character count_, but Lucene counts bytes. Here we set the limit to `32766 / 4 = 8191` since UTF-8 characters may occupy at most 4 bytes.
1 parent 6425c61 commit 521e434

File tree

4 files changed

+90
-3
lines changed

4 files changed

+90
-3
lines changed

modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/logsdb/LogsIndexModeCustomSettingsIT.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.elasticsearch.common.settings.Settings;
1616
import org.elasticsearch.test.cluster.ElasticsearchCluster;
1717
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
18+
import org.hamcrest.Matchers;
1819
import org.junit.Before;
1920
import org.junit.ClassRule;
2021

@@ -357,6 +358,66 @@ public void testIgnoreMalformedSetting() throws IOException {
357358
}
358359
}
359360

361+
public void testIgnoreAboveSetting() throws IOException {
362+
// with default template
363+
{
364+
assertOK(createDataStream(client, "logs-test-1"));
365+
String logsIndex1 = getDataStreamBackingIndex(client, "logs-test-1", 0);
366+
assertThat(getSetting(client, logsIndex1, "index.mapping.ignore_above"), equalTo("8191"));
367+
for (String newValue : List.of("512", "2048", "12000", String.valueOf(Integer.MAX_VALUE))) {
368+
closeIndex(logsIndex1);
369+
updateIndexSettings(logsIndex1, Settings.builder().put("index.mapping.ignore_above", newValue));
370+
assertThat(getSetting(client, logsIndex1, "index.mapping.ignore_above"), equalTo(newValue));
371+
}
372+
for (String newValue : List.of(String.valueOf((long) Integer.MAX_VALUE + 1), String.valueOf(Long.MAX_VALUE))) {
373+
closeIndex(logsIndex1);
374+
ResponseException ex = assertThrows(
375+
ResponseException.class,
376+
() -> updateIndexSettings(logsIndex1, Settings.builder().put("index.mapping.ignore_above", newValue))
377+
);
378+
assertThat(
379+
ex.getMessage(),
380+
Matchers.containsString("Failed to parse value [" + newValue + "] for setting [index.mapping.ignore_above]")
381+
);
382+
}
383+
}
384+
// with override template
385+
{
386+
var template = """
387+
{
388+
"template": {
389+
"settings": {
390+
"index": {
391+
"mapping": {
392+
"ignore_above": "128"
393+
}
394+
}
395+
}
396+
}
397+
}""";
398+
assertOK(putComponentTemplate(client, "logs@custom", template));
399+
assertOK(createDataStream(client, "logs-custom-dev"));
400+
String index = getDataStreamBackingIndex(client, "logs-custom-dev", 0);
401+
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo("128"));
402+
for (String newValue : List.of("64", "256", "12000", String.valueOf(Integer.MAX_VALUE))) {
403+
closeIndex(index);
404+
updateIndexSettings(index, Settings.builder().put("index.mapping.ignore_above", newValue));
405+
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo(newValue));
406+
}
407+
}
408+
// standard index
409+
{
410+
String index = "test-index";
411+
createIndex(index);
412+
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo(Integer.toString(Integer.MAX_VALUE)));
413+
for (String newValue : List.of("256", "512", "12000", String.valueOf(Integer.MAX_VALUE))) {
414+
closeIndex(index);
415+
updateIndexSettings(index, Settings.builder().put("index.mapping.ignore_above", newValue));
416+
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo(newValue));
417+
}
418+
}
419+
}
420+
360421
private static Map<String, Object> getMapping(final RestClient client, final String indexName) throws IOException {
361422
final Request request = new Request("GET", "/" + indexName + "/_mapping");
362423

server/src/main/java/org/elasticsearch/common/settings/Setting.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,16 @@ public static Setting<Integer> intSetting(String key, int defaultValue, int minV
13661366
return new Setting<>(key, Integer.toString(defaultValue), intParser(key, minValue, properties), properties);
13671367
}
13681368

1369+
public static Setting<Integer> intSetting(
1370+
String key,
1371+
Function<Settings, String> defaultValueFn,
1372+
int minValue,
1373+
int maxValue,
1374+
Property... properties
1375+
) {
1376+
return new Setting<>(key, defaultValueFn, intParser(key, minValue, maxValue, properties), properties);
1377+
}
1378+
13691379
private static Function<String, Integer> intParser(String key, int minValue, Property[] properties) {
13701380
final boolean isFiltered = isFiltered(properties);
13711381
return s -> parseInt(s, minValue, key, isFiltered);

server/src/main/java/org/elasticsearch/index/IndexSettings.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ public Iterator<Setting<?>> settings() {
701701
/**
702702
* The `index.mapping.ignore_above` setting defines the maximum length for the content of a field that will be indexed
703703
* or stored. If the length of the field’s content exceeds this limit, the field value will be ignored during indexing.
704-
* This setting is useful for `keyword`, `flattened`, and `wildcard` fields where very large values are undesirable.
704+
* This setting is useful for `keyword`, `flattened`, and `wildcard` fields where very large values are undesirable.
705705
* It allows users to manage the size of indexed data by skipping fields with excessively long content. As an index-level
706706
* setting, it applies to all `keyword` and `wildcard` fields, as well as to keyword values within `flattened` fields.
707707
* When it comes to arrays, the `ignore_above` setting applies individually to each element of the array. If any element's
@@ -713,14 +713,30 @@ public Iterator<Setting<?>> settings() {
713713
* <pre>
714714
* "index.mapping.ignore_above": 256
715715
* </pre>
716+
* <p>
717+
* NOTE: The value for `ignore_above` is the _character count_, but Lucene counts
718+
* bytes. Here we set the limit to `32766 / 4 = 8191` since UTF-8 characters may
719+
* occupy at most 4 bytes.
716720
*/
721+
717722
public static final Setting<Integer> IGNORE_ABOVE_SETTING = Setting.intSetting(
718723
"index.mapping.ignore_above",
719-
Integer.MAX_VALUE,
724+
IndexSettings::getIgnoreAboveDefaultValue,
720725
0,
726+
Integer.MAX_VALUE,
721727
Property.IndexScope,
722728
Property.ServerlessPublic
723729
);
730+
731+
private static String getIgnoreAboveDefaultValue(final Settings settings) {
732+
if (IndexSettings.MODE.get(settings) == IndexMode.LOGSDB
733+
&& IndexMetadata.SETTING_INDEX_VERSION_CREATED.get(settings).onOrAfter(IndexVersions.ENABLE_IGNORE_ABOVE_LOGSDB)) {
734+
return "8191";
735+
} else {
736+
return String.valueOf(Integer.MAX_VALUE);
737+
}
738+
}
739+
724740
public static final NodeFeature IGNORE_ABOVE_INDEX_LEVEL_SETTING = new NodeFeature("mapper.ignore_above_index_level_setting");
725741

726742
private final Index index;

server/src/main/java/org/elasticsearch/index/IndexVersions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private static IndexVersion def(int id, Version luceneVersion) {
117117
public static final IndexVersion ENABLE_IGNORE_MALFORMED_LOGSDB = def(8_514_00_0, Version.LUCENE_9_11_1);
118118
public static final IndexVersion MERGE_ON_RECOVERY_VERSION = def(8_515_00_0, Version.LUCENE_9_11_1);
119119
public static final IndexVersion UPGRADE_TO_LUCENE_9_12 = def(8_516_00_0, Version.LUCENE_9_12_0);
120-
120+
public static final IndexVersion ENABLE_IGNORE_ABOVE_LOGSDB = def(8_517_00_0, Version.LUCENE_9_12_0);
121121
/*
122122
* STOP! READ THIS FIRST! No, really,
123123
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _

0 commit comments

Comments
 (0)