Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
83b507c
Add new dynamic until_limit option
felixbarny May 19, 2023
2993820
Add setting
felixbarny May 20, 2023
6402346
Update docs/changelog/96235.yaml
felixbarny May 20, 2023
0407747
Fix test
felixbarny May 20, 2023
677f749
Prevent infinite retry loops and simplify code by retrying all mappin…
felixbarny May 21, 2023
0634d26
Avoid catching exception
felixbarny May 24, 2023
9d3b685
Fix constant_keyword mapping
felixbarny May 24, 2023
ec511c7
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Jul 9, 2023
7408c5d
Add mappingUpdateRetryCounter
felixbarny Jul 9, 2023
05dee62
Add comment to _ignored field's exists query implementation
felixbarny Jul 9, 2023
2d2c9c2
Refactor index setting into `dynamic: until_limit` mapping parameter
felixbarny Jul 10, 2023
c9ad4f3
Fix testExecuteBulkIndexRequestWithErrorWhileUpdatingMapping
felixbarny Jul 10, 2023
72a02ed
Remove references to ignore_dynamic_beyond_limit in docs
felixbarny Aug 3, 2023
180bec1
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Aug 3, 2023
d446da9
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Aug 29, 2023
0f8029d
Accept mappers with the same name
felixbarny Aug 31, 2023
51280ae
Apply spotless suggestions
felixbarny Aug 31, 2023
99ce1a9
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 7, 2023
9528a12
Avoid double counting dynamic mappers for dynamic array values
felixbarny Sep 7, 2023
9ab71ad
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 7, 2023
055f849
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 11, 2023
db224bd
Apply feedback from review
felixbarny Sep 13, 2023
92a1f1a
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 13, 2023
a0e5a01
Test and fix bug in Mapper#mapperSize
felixbarny Sep 13, 2023
def096d
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 13, 2023
2ea9418
Address nits
felixbarny Sep 14, 2023
b7ab897
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 14, 2023
df8af69
Make mappingUpdateRetryCounter a boolean
felixbarny Sep 14, 2023
6d06795
Only retry failed mapping updates when mappings have been updated con…
felixbarny Sep 14, 2023
94996cc
Apply spotless suggestions
felixbarny Sep 14, 2023
7880073
Compare total fields count rather than mapping version to check for c…
felixbarny Sep 15, 2023
a967603
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 20, 2023
f146cdf
Move mapperSize implementation from Mapper to Mapper.Builder
felixbarny Sep 20, 2023
b8a7a49
Apply spotless suggestions
felixbarny Sep 20, 2023
ca1c5b7
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 20, 2023
e1ff5a0
Revert TransportShardBulkActionTests changes
felixbarny Sep 20, 2023
4bae69a
More tests for Mapper.Builder#mapperSize
felixbarny Sep 20, 2023
d98ec65
Suppress unchecked warning
felixbarny Sep 20, 2023
6824f73
Fix LegacyGeoShapeFieldMapperTests via assertWarnings
felixbarny Sep 20, 2023
df1483c
Retry mapping updates if mapping was updated concurrently
felixbarny Sep 21, 2023
b0b957e
Apply spotless suggestions
felixbarny Sep 21, 2023
6d133d1
Guard against NPE
felixbarny Sep 21, 2023
5ca08fb
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Sep 25, 2023
7ddc5ae
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Nov 16, 2023
da99d7a
Revert changes to retry mapping update
felixbarny Nov 16, 2023
5f3b6dc
Limit the number of fields added during merge
felixbarny Nov 22, 2023
fac8dcb
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Nov 22, 2023
41da12a
Fix mapperSize for some FieldMapper builders
felixbarny Nov 24, 2023
1a735bd
Guard against mapping update request timeouts and infinite loops
felixbarny Nov 24, 2023
bd56de6
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Nov 24, 2023
f1413c4
Fix test and spotless
felixbarny Nov 24, 2023
0727ce6
A couple of fixes
felixbarny Nov 25, 2023
75acf0c
More field mapper test fixes
felixbarny Nov 25, 2023
54028bf
Remove unused import
felixbarny Nov 25, 2023
a0a0006
Adding diagnostics to debug build failure
felixbarny Nov 26, 2023
b3c8fda
Only throw if mapping version hasn't changed
felixbarny Nov 27, 2023
3656003
Add test case for infinite loop prevention
felixbarny Nov 27, 2023
435faf5
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Nov 27, 2023
1bd80fb
Add unit test for getNewDynamicMappersSize
felixbarny Nov 27, 2023
797e9ee
Revert "Refactor index setting into `dynamic: until_limit` mapping pa…
felixbarny Dec 1, 2023
4865ac0
Remove remains of true_until_limit
felixbarny Dec 1, 2023
470d192
Simplify MapperMergeContext by using ignore_dynamic_beyond_limit inde…
felixbarny Dec 1, 2023
7286290
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Dec 1, 2023
42a6f7e
Apply spotless suggestions
felixbarny Dec 1, 2023
379ff2b
Fix bug in addDynamicRuntimeField
felixbarny Dec 1, 2023
be47036
Revert adding unnecessary new line
felixbarny Dec 1, 2023
58426e5
Determine remaining fields to add in MapperService
felixbarny Dec 4, 2023
bd99efa
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Dec 4, 2023
6948a08
Polishing
felixbarny Dec 4, 2023
a71fbf3
Don't preserve order in mappers
felixbarny Dec 5, 2023
4ad0bca
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Dec 6, 2023
1f44c30
Fix performance regression
felixbarny Dec 6, 2023
94f25f5
Apply spotless suggestions
felixbarny Dec 6, 2023
c56d18b
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Jan 4, 2024
0c53952
Fix SemanticTextFieldMapperTests
felixbarny Jan 4, 2024
cd0cc41
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Jan 5, 2024
80d0c66
Remove Mapper.Builder#mapperSize
felixbarny Jan 5, 2024
6aab0ad
Remove unused import
felixbarny Jan 5, 2024
4c07538
Adapt DocumentParserContextTests
felixbarny Jan 5, 2024
3bcefac
Apply spotless suggestions
felixbarny Jan 5, 2024
baf3ab6
Fix RootObjectMapper#mapperSize
felixbarny Jan 5, 2024
ef45686
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Jan 23, 2024
e9d3652
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Jan 23, 2024
d38de54
Remove unused method
felixbarny Jan 23, 2024
cdd0ce6
Fix SearchResponse leak in DynamicMappingIT
felixbarny Jan 23, 2024
90390ee
Merge branch 'main' into ignore-dynamic-beyond-limit
elasticmachine Jan 24, 2024
f589bac
Merge branch 'main' into ignore-dynamic-beyond-limit
elasticmachine Jan 24, 2024
49191bf
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Jan 26, 2024
eade390
Add docs for `index.mapping.total_fields.ignore_dynamic_beyond_limit`
felixbarny Jan 29, 2024
488befa
Align exceedsLimit with remainingFieldsUntilLimit
felixbarny Jan 29, 2024
58f900f
Make setters in IndexSettings private
felixbarny Jan 29, 2024
9efde90
Replace AtomicInteger with a private DynamicMapperSize class
felixbarny Jan 31, 2024
5b462d4
Make MapperService#mergeMappings static again
felixbarny Jan 31, 2024
f27c88c
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Jan 31, 2024
da16f8d
Merge remote-tracking branch 'origin/main' into ignore-dynamic-beyond…
felixbarny Feb 1, 2024
381a5d0
Merge branch 'main' into ignore-dynamic-beyond-limit
elasticmachine Feb 2, 2024
43d7412
Merge branch 'main' into ignore-dynamic-beyond-limit
elasticmachine Feb 2, 2024
059132d
Merge branch 'main' into ignore-dynamic-beyond-limit
elasticmachine Feb 2, 2024
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
5 changes: 5 additions & 0 deletions docs/changelog/96235.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 96235
summary: Add `index.mapping.total_fields.ignore_dynamic_beyond_limit` setting to ignore dynamic fields when field limit is reached
area: Mapping
type: enhancement
issues: []
7 changes: 5 additions & 2 deletions docs/reference/mapping/fields/ignored-field.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
The `_ignored` field indexes and stores the names of every field in a document
that has been ignored when the document was indexed. This can, for example,
be the case when the field was malformed and <<ignore-malformed,`ignore_malformed`>>
was turned on, or when a `keyword` fields value exceeds its optional
<<ignore-above,`ignore_above`>> setting.
was turned on, when a `keyword` field's value exceeds its optional
<<ignore-above,`ignore_above`>> setting, or when
<<mapping-settings-limit,`index.mapping.total_fields.limit`>> has been reached and
<<mapping-settings-limit,`index.mapping.total_fields.ignore_dynamic_beyond_limit`>>
is set to `true`.

This field is searchable with <<query-dsl-term-query,`term`>>,
<<query-dsl-terms-query,`terms`>> and <<query-dsl-exists-query,`exists`>>
Expand Down
11 changes: 10 additions & 1 deletion docs/reference/mapping/mapping-settings-limit.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,18 @@ limits the maximum number of clauses in a query.
+
[TIP]
====
If your field mappings contain a large, arbitrary set of keys, consider using the <<flattened,flattened>> data type.
If your field mappings contain a large, arbitrary set of keys, consider using the <<flattened,flattened>> data type,
or setting the index setting `index.mapping.total_fields.ignore_dynamic_beyond_limit` to `true`.
====

`index.mapping.total_fields.ignore_dynamic_beyond_limit`::
This setting determines what happens when a dynamically mapped field would exceed the total fields limit.
When set to `false` (the default), the index request of the document that tries to add a dynamic field to the mapping will fail with the message `Limit of total fields [X] has been exceeded`.
When set to `true`, the index request will not fail.
Instead, fields that would exceed the limit are not added to the mapping, similar to <<dynamic, `dynamic: false`>>.
The fields that were not added to the mapping will be added to the <<mapping-ignored-field, `_ignored` field>>.
The default value is `false`.

`index.mapping.depth.limit`::
The maximum depth for a field, which is measured as the number of inner
objects. For instance, if all fields are defined at the root object level,
Expand Down
7 changes: 7 additions & 0 deletions docs/reference/mapping/params/dynamic.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,10 @@ accepts the following parameters:
to the mapping, and new fields must be added explicitly.
`strict`:: If new fields are detected, an exception is thrown and the document
is rejected. New fields must be explicitly added to the mapping.

[[dynamic-field-limit]]
==== Behavior when reaching the field limit
Setting `dynamic` to either `true` or `runtime` will only add dynamic fields until <<mapping-settings-limit,`index.mapping.total_fields.limit`>> is reached.
By default, index requests for documents that would exceed the field limit will fail,
unless <<mapping-settings-limit,`index.mapping.total_fields.ignore_dynamic_beyond_limit`>> is set to `true`.
In that case, ignored fields are added to the <<mapping-ignored-field, `_ignored` metadata field>>.
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ timing out in the browser's Developer Tools Network tab.
doesn't normally cause problems unless it's combined with overriding
<<mapping-settings-limit,`index.mapping.total_fields.limit`>>. The
default `1000` limit is considered generous, though overriding to `10000`
doesn't cause noticable impact depending on use case. However, to give
doesn't cause noticeable impact depending on use case. However, to give
a bad example, overriding to `100000` and this limit being hit
by mapping totals would usually have strong performance implications.

If your index mapped fields expect to contain a large, arbitrary set of
keys, you may instead consider:

* Setting <<mapping-settings-limit,`index.mapping.total_fields.ignore_dynamic_beyond_limit`>> to `true`.
Comment thread
javanna marked this conversation as resolved.
Instead of rejecting documents that exceed the field limit, this will ignore dynamic fields once the limit is reached.

* Using the <<flattened,flattened>> data type. Please note,
however, that flattened objects is link:https://github.com/elastic/kibana/issues/25820[not fully supported in {kib}] yet. For example, this could apply to sub-mappings like { `host.name` ,
`host.os`, `host.version` }. Desired fields are still accessed by
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ private static ClusterState applyRequest(
MapperService.mergeMappings(
mapperService.documentMapper(),
mapping,
request.autoUpdate() ? MergeReason.MAPPING_AUTO_UPDATE : MergeReason.MAPPING_UPDATE
request.autoUpdate() ? MergeReason.MAPPING_AUTO_UPDATE : MergeReason.MAPPING_UPDATE,
mapperService.getIndexSettings()
);
}
Metadata.Builder builder = Metadata.builder(metadata);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
Store.INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING,
MapperService.INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING,
MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING,
MapperService.INDEX_MAPPING_IGNORE_DYNAMIC_BEYOND_LIMIT_SETTING,
MapperService.INDEX_MAPPING_TOTAL_FIELDS_LIMIT_SETTING,
MapperService.INDEX_MAPPING_DEPTH_LIMIT_SETTING,
MapperService.INDEX_MAPPING_DIMENSION_FIELDS_LIMIT_SETTING,
Expand Down
15 changes: 15 additions & 0 deletions server/src/main/java/org/elasticsearch/index/IndexSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_DEPTH_LIMIT_SETTING;
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_DIMENSION_FIELDS_LIMIT_SETTING;
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_FIELD_NAME_LENGTH_LIMIT_SETTING;
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_IGNORE_DYNAMIC_BEYOND_LIMIT_SETTING;
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING;
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING;
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_TOTAL_FIELDS_LIMIT_SETTING;
Expand Down Expand Up @@ -753,6 +754,7 @@ private void setRetentionLeaseMillis(final TimeValue retentionLease) {
private volatile long mappingNestedFieldsLimit;
private volatile long mappingNestedDocsLimit;
private volatile long mappingTotalFieldsLimit;
private volatile boolean ignoreDynamicFieldsBeyondLimit;
private volatile long mappingDepthLimit;
private volatile long mappingFieldNameLengthLimit;
private volatile long mappingDimensionFieldsLimit;
Expand Down Expand Up @@ -897,6 +899,7 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
mappingNestedFieldsLimit = scopedSettings.get(INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING);
mappingNestedDocsLimit = scopedSettings.get(INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING);
mappingTotalFieldsLimit = scopedSettings.get(INDEX_MAPPING_TOTAL_FIELDS_LIMIT_SETTING);
ignoreDynamicFieldsBeyondLimit = scopedSettings.get(INDEX_MAPPING_IGNORE_DYNAMIC_BEYOND_LIMIT_SETTING);
mappingDepthLimit = scopedSettings.get(INDEX_MAPPING_DEPTH_LIMIT_SETTING);
mappingFieldNameLengthLimit = scopedSettings.get(INDEX_MAPPING_FIELD_NAME_LENGTH_LIMIT_SETTING);
mappingDimensionFieldsLimit = scopedSettings.get(INDEX_MAPPING_DIMENSION_FIELDS_LIMIT_SETTING);
Expand Down Expand Up @@ -976,6 +979,10 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
scopedSettings.addSettingsUpdateConsumer(INDEX_SOFT_DELETES_RETENTION_LEASE_PERIOD_SETTING, this::setRetentionLeaseMillis);
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING, this::setMappingNestedFieldsLimit);
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING, this::setMappingNestedDocsLimit);
scopedSettings.addSettingsUpdateConsumer(
INDEX_MAPPING_IGNORE_DYNAMIC_BEYOND_LIMIT_SETTING,
this::setIgnoreDynamicFieldsBeyondLimit
);
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_TOTAL_FIELDS_LIMIT_SETTING, this::setMappingTotalFieldsLimit);
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_DEPTH_LIMIT_SETTING, this::setMappingDepthLimit);
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_FIELD_NAME_LENGTH_LIMIT_SETTING, this::setMappingFieldNameLengthLimit);
Expand Down Expand Up @@ -1519,6 +1526,14 @@ private void setMappingTotalFieldsLimit(long value) {
this.mappingTotalFieldsLimit = value;
}

private void setIgnoreDynamicFieldsBeyondLimit(boolean ignoreDynamicFieldsBeyondLimit) {
this.ignoreDynamicFieldsBeyondLimit = ignoreDynamicFieldsBeyondLimit;
}

public boolean isIgnoreDynamicFieldsBeyondLimit() {
return ignoreDynamicFieldsBeyondLimit;
}

public long getMappingDepthLimit() {
return mappingDepthLimit;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -629,11 +629,6 @@ public DeleteResult(Exception failure, long version, long term, long seqNo, bool
this.found = found;
}

public DeleteResult(Mapping requiredMappingUpdate, String id) {
super(Operation.TYPE.DELETE, requiredMappingUpdate, id);
this.found = false;
}

public boolean isFound() {
return found;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,11 @@ private static void parseObjectDynamic(DocumentParserContext context, String cur

}
if (context.dynamic() != ObjectMapper.Dynamic.RUNTIME) {
context.addDynamicMapper(dynamicObjectMapper);
if (context.addDynamicMapper(dynamicObjectMapper) == false) {
failIfMatchesRoutingPath(context, currentFieldName);
context.parser().skipChildren();
return;
}
}
if (dynamicObjectMapper instanceof NestedObjectMapper && context.isWithinCopyTo()) {
throwOnCreateDynamicNestedViaCopyTo(dynamicObjectMapper, context);
Expand Down Expand Up @@ -556,7 +560,10 @@ private static void parseArrayDynamic(DocumentParserContext context, String curr
parseNonDynamicArray(context, currentFieldName, currentFieldName);
} else {
if (parsesArrayValue(objectMapperFromTemplate)) {
context.addDynamicMapper(objectMapperFromTemplate);
if (context.addDynamicMapper(objectMapperFromTemplate) == false) {
context.parser().skipChildren();
return;
}
context.path().add(currentFieldName);
parseObjectOrField(context, objectMapperFromTemplate);
context.path().remove();
Expand Down Expand Up @@ -674,7 +681,9 @@ private static void parseDynamicValue(final DocumentParserContext context, Strin
failIfMatchesRoutingPath(context, currentFieldName);
return;
}
context.dynamic().getDynamicFieldsBuilder().createDynamicFieldFromValue(context, currentFieldName);
if (context.dynamic().getDynamicFieldsBuilder().createDynamicFieldFromValue(context, currentFieldName) == false) {
failIfMatchesRoutingPath(context, currentFieldName);
Comment thread
javanna marked this conversation as resolved.
}
}

private static void ensureNotStrict(DocumentParserContext context, String currentFieldName) {
Expand Down
Loading