Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1371,7 +1371,27 @@ public static Setting<Integer> intSetting(String key, int defaultValue, int minV
}

public static Setting<Integer> intSetting(String key, int defaultValue, int minValue, Property... properties) {
return new Setting<>(key, Integer.toString(defaultValue), (s) -> parseInt(s, minValue, key, isFiltered(properties)), properties);
return new Setting<>(key, Integer.toString(defaultValue), intParser(key, minValue, properties), properties);
}

public static Setting<Integer> intSetting(
String key,
Function<Settings, String> defaultValueFn,
int minValue,
int maxValue,
Property... properties
) {
return new Setting<>(key, defaultValueFn, intParser(key, minValue, maxValue, properties), properties);
}

private static Function<String, Integer> intParser(String key, int minValue, Property[] properties) {
final boolean isFiltered = isFiltered(properties);
return s -> parseInt(s, minValue, key, isFiltered);
}

private static Function<String, Integer> intParser(String key, int minValue, int maxValue, Property[] properties) {
boolean isFiltered = isFiltered(properties);
return s -> parseInt(s, minValue, maxValue, key, isFiltered);
}

public static Setting<Integer> intSetting(
Expand Down
20 changes: 18 additions & 2 deletions server/src/main/java/org/elasticsearch/index/IndexSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ public Iterator<Setting<?>> settings() {
/**
* The `index.mapping.ignore_above` setting defines the maximum length for the content of a field that will be indexed
* or stored. If the length of the field’s content exceeds this limit, the field value will be ignored during indexing.
* This setting is useful for `keyword`, `flattened`, and `wildcard` fields where very large values are undesirable.
* This setting is useful for `keyword`, `flattened`, and `wildcard` fields where very large values are undesirable.
* It allows users to manage the size of indexed data by skipping fields with excessively long content. As an index-level
* setting, it applies to all `keyword` and `wildcard` fields, as well as to keyword values within `flattened` fields.
* When it comes to arrays, the `ignore_above` setting applies individually to each element of the array. If any element's
Expand All @@ -725,14 +725,30 @@ public Iterator<Setting<?>> settings() {
* <pre>
* "index.mapping.ignore_above": 256
* </pre>
* <p>
* NOTE: 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.
*/

public static final Setting<Integer> IGNORE_ABOVE_SETTING = Setting.intSetting(
"index.mapping.ignore_above",
Integer.MAX_VALUE,
IndexSettings::getIgnoreAboveDefaultValue,
0,
Integer.MAX_VALUE,
Property.IndexScope,
Property.ServerlessPublic
);

private static String getIgnoreAboveDefaultValue(final Settings settings) {
if (IndexSettings.MODE.get(settings) == IndexMode.LOGSDB
&& IndexMetadata.SETTING_INDEX_VERSION_CREATED.get(settings).onOrAfter(IndexVersions.ENABLE_IGNORE_ABOVE_LOGSDB)) {
return "8191";
} else {
return String.valueOf(Integer.MAX_VALUE);
}
}

public static final NodeFeature IGNORE_ABOVE_INDEX_LEVEL_SETTING = new NodeFeature("mapper.ignore_above_index_level_setting");

private final Index index;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private static IndexVersion def(int id, Version luceneVersion) {
public static final IndexVersion ENABLE_IGNORE_MALFORMED_LOGSDB = def(8_514_00_0, Version.LUCENE_9_11_1);
public static final IndexVersion MERGE_ON_RECOVERY_VERSION = def(8_515_00_0, Version.LUCENE_9_11_1);
public static final IndexVersion UPGRADE_TO_LUCENE_9_12 = def(8_516_00_0, Version.LUCENE_9_12_0);

public static final IndexVersion ENABLE_IGNORE_ABOVE_LOGSDB = def(8_517_00_0, Version.LUCENE_9_12_0);
/*
* STOP! READ THIS FIRST! No, really,
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.cluster.ElasticsearchCluster;
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.ClassRule;

Expand Down Expand Up @@ -436,6 +437,66 @@ public void testIgnoreMalformedSetting() throws IOException {
}
}

public void testIgnoreAboveSetting() throws IOException {
// with default template
{
assertOK(createDataStream(client, "logs-test-1"));
String logsIndex1 = getDataStreamBackingIndex(client, "logs-test-1", 0);
assertThat(getSetting(client, logsIndex1, "index.mapping.ignore_above"), equalTo("8191"));
for (String newValue : List.of("512", "2048", "12000", String.valueOf(Integer.MAX_VALUE))) {
closeIndex(logsIndex1);
updateIndexSettings(logsIndex1, Settings.builder().put("index.mapping.ignore_above", newValue));
assertThat(getSetting(client, logsIndex1, "index.mapping.ignore_above"), equalTo(newValue));
}
for (String newValue : List.of(String.valueOf((long) Integer.MAX_VALUE + 1), String.valueOf(Long.MAX_VALUE))) {
closeIndex(logsIndex1);
ResponseException ex = assertThrows(
ResponseException.class,
() -> updateIndexSettings(logsIndex1, Settings.builder().put("index.mapping.ignore_above", newValue))
);
assertThat(
ex.getMessage(),
Matchers.containsString("Failed to parse value [" + newValue + "] for setting [index.mapping.ignore_above]")
);
}
}
// with override template
{
var template = """
{
"template": {
"settings": {
"index": {
"mapping": {
"ignore_above": "128"
}
}
}
}
}""";
assertOK(putComponentTemplate(client, "logs@custom", template));
assertOK(createDataStream(client, "logs-custom-dev"));
String index = getDataStreamBackingIndex(client, "logs-custom-dev", 0);
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo("128"));
for (String newValue : List.of("64", "256", "12000", String.valueOf(Integer.MAX_VALUE))) {
closeIndex(index);
updateIndexSettings(index, Settings.builder().put("index.mapping.ignore_above", newValue));
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo(newValue));
}
}
// standard index
{
String index = "test-index";
createIndex(index);
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo(Integer.toString(Integer.MAX_VALUE)));
for (String newValue : List.of("256", "512", "12000", String.valueOf(Integer.MAX_VALUE))) {
closeIndex(index);
updateIndexSettings(index, Settings.builder().put("index.mapping.ignore_above", newValue));
assertThat(getSetting(client, index, "index.mapping.ignore_above"), equalTo(newValue));
}
}
}

private static Map<String, Object> getMapping(final RestClient client, final String indexName) throws IOException {
final Request request = new Request("GET", "/" + indexName + "/_mapping");

Expand Down