Skip to content

Commit 2351aa3

Browse files
author
Christoph Büscher
authored
Disallow _field_names enabled setting (#46681)
After deprecating the `enabled` setting for `_field_names`starting with 7.5, this change disallows the setting on new indices in 8.0. The setting continues to work for indices created in 7.x where we continue emitting a deprecation warning. Relates to #42854
1 parent 3074bd1 commit 2351aa3

File tree

5 files changed

+60
-74
lines changed

5 files changed

+60
-74
lines changed

docs/reference/mapping/fields/field-names-field.asciidoc

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,9 @@ be available but will not use the `_field_names` field.
1414
[[disable-field-names]]
1515
==== Disabling `_field_names`
1616

17-
NOTE: Disabling `_field_names` has been deprecated and will be removed in a future major version.
17+
Disabling `_field_names` is no longer possible. It is now enabled by default
18+
because it no longer carries the index overhead it once did.
1819

19-
Disabling `_field_names` is usually not necessary because it no longer
20-
carries the index overhead it once did. If you have a lot of fields
21-
which have `doc_values` and `norms` disabled and you do not need to
22-
execute `exists` queries using those fields you might want to disable
23-
`_field_names` by adding the following to the mappings:
24-
25-
[source,console]
26-
--------------------------------------------------
27-
PUT tweets
28-
{
29-
"mappings": {
30-
"_field_names": {
31-
"enabled": false
32-
}
33-
}
34-
}
35-
--------------------------------------------------
36-
// TEST[warning:Index [tweets] uses the deprecated `enabled` setting for `_field_names`. Disabling _field_names is not necessary because it no longer carries a large index overhead. Support for this setting will be removed in a future major version. Please remove it from your mappings and templates.]
20+
NOTE: Support for disabling `_field_names` has been removed. Using it on new
21+
indices will throw an error. Using it in pre-8.0 indices is still allowed but
22+
issues a deprecation warning.

docs/reference/migration/migrate_8_0/mappings.asciidoc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,13 @@ Previously, it was possible to define a multi-field within a multi-field.
2222
Defining chained multi-fields was deprecated in 7.3 and is now no longer
2323
supported. To migrate the mappings, all instances of `fields` that occur within
2424
a `fields` block should be removed, either by flattening the chained `fields`
25-
blocks into a single level, or by switching to `copy_to` if appropriate.
25+
blocks into a single level, or by switching to `copy_to` if appropriate.
26+
27+
[float]
28+
[[fieldnames-enabling]]
29+
==== Disallow use of the `enabled` setting on the `_field_names` field
30+
31+
The setting has been deprecated with 7.5 and is no longer supported on new indices.
32+
Mappings for older indices will continue to work but emit a deprecation warning.
33+
The `enabled` setting for `_field_names` should be removed from templates and mappings.
34+
Disabling _field_names is not necessary because it no longer carries a large index overhead.

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.lucene.index.IndexOptions;
2525
import org.apache.lucene.index.IndexableField;
2626
import org.apache.lucene.search.Query;
27+
import org.elasticsearch.Version;
2728
import org.elasticsearch.common.logging.DeprecationLogger;
2829
import org.elasticsearch.common.lucene.Lucene;
2930
import org.elasticsearch.common.settings.Settings;
@@ -47,8 +48,7 @@
4748
*/
4849
public class FieldNamesFieldMapper extends MetadataFieldMapper {
4950

50-
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
51-
LogManager.getLogger(FieldNamesFieldMapper.class));
51+
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(FieldNamesFieldMapper.class));
5252

5353
public static final String NAME = "_field_names";
5454

@@ -111,8 +111,13 @@ public MetadataFieldMapper.Builder<?,?> parse(String name, Map<String, Object> n
111111
Object fieldNode = entry.getValue();
112112
if (fieldName.equals("enabled")) {
113113
String indexName = parserContext.mapperService().index().getName();
114-
deprecationLogger.deprecatedAndMaybeLog("field_names_enabled_parameter", ENABLED_DEPRECATION_MESSAGE, indexName);
115-
builder.enabled(XContentMapValues.nodeBooleanValue(fieldNode, name + ".enabled"));
114+
if (parserContext.indexVersionCreated().onOrAfter(Version.V_8_0_0)) {
115+
throw new MapperParsingException("The `enabled` setting for the `_field_names` field has been deprecated and "
116+
+ "removed but is still used in index [{}]. Please remove it from your mappings and templates.");
117+
} else {
118+
deprecationLogger.deprecatedAndMaybeLog("field_names_enabled_parameter", ENABLED_DEPRECATION_MESSAGE, indexName);
119+
builder.enabled(XContentMapValues.nodeBooleanValue(fieldNode, name + ".enabled"));
120+
}
116121
iterator.remove();
117122
}
118123
}

server/src/test/java/org/elasticsearch/index/mapper/FieldNamesFieldMapperTests.java

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@
2020
package org.elasticsearch.index.mapper;
2121

2222
import org.apache.lucene.index.IndexOptions;
23+
import org.elasticsearch.Version;
24+
import org.elasticsearch.cluster.metadata.IndexMetaData;
2325
import org.elasticsearch.common.Strings;
2426
import org.elasticsearch.common.bytes.BytesReference;
2527
import org.elasticsearch.common.compress.CompressedXContent;
28+
import org.elasticsearch.common.settings.Settings;
2629
import org.elasticsearch.common.xcontent.XContentFactory;
2730
import org.elasticsearch.common.xcontent.XContentType;
2831
import org.elasticsearch.test.ESSingleNodeTestCase;
32+
import org.elasticsearch.test.VersionUtils;
2933

3034
import java.util.Arrays;
3135
import java.util.Collections;
@@ -95,33 +99,33 @@ public void testInjectIntoDocDuringParsing() throws Exception {
9599
assertFieldNames(Collections.emptySet(), doc);
96100
}
97101

98-
public void testExplicitEnabled() throws Exception {
102+
public void testUsingEnabledSettingThrows() throws Exception {
99103
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
100104
.startObject("_field_names").field("enabled", true).endObject()
101105
.startObject("properties")
102106
.startObject("field").field("type", "keyword").field("doc_values", false).endObject()
103107
.endObject().endObject().endObject());
104-
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser()
105-
.parse("type", new CompressedXContent(mapping));
106-
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
107-
assertTrue(fieldNamesMapper.fieldType().isEnabled());
108+
MapperParsingException ex = expectThrows(MapperParsingException.class,
109+
() -> createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping)));
108110

109-
ParsedDocument doc = docMapper.parse(new SourceToParse("test", "type", "1",
110-
BytesReference.bytes(XContentFactory.jsonBuilder()
111-
.startObject()
112-
.field("field", "value")
113-
.endObject()),
114-
XContentType.JSON));
115-
116-
assertFieldNames(set("field"), doc);
117-
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", "test"));
111+
assertEquals("The `enabled` setting for the `_field_names` field has been deprecated and removed but is still used in index [{}]. "
112+
+ "Please remove it from your mappings and templates.", ex.getMessage());
118113
}
119114

120-
public void testDisabled() throws Exception {
115+
/**
116+
* disabling the _field_names should still work for indices before 8.0
117+
*/
118+
public void testUsingEnabledBefore8() throws Exception {
121119
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
122120
.startObject("_field_names").field("enabled", false).endObject()
123121
.endObject().endObject());
124-
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser()
122+
123+
DocumentMapper docMapper = createIndex("test",
124+
Settings.builder()
125+
.put(IndexMetaData.SETTING_INDEX_VERSION_CREATED.getKey(),
126+
VersionUtils.randomPreviousCompatibleVersion(random(), Version.V_8_0_0))
127+
.build()).mapperService()
128+
.documentMapperParser()
125129
.parse("type", new CompressedXContent(mapping));
126130
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
127131
assertFalse(fieldNamesMapper.fieldType().isEnabled());
@@ -137,14 +141,20 @@ public void testDisabled() throws Exception {
137141
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", "test"));
138142
}
139143

140-
public void testMergingMappings() throws Exception {
144+
/**
145+
* Merging the "_field_names" enabled setting is forbidden in 8.0, but we still want to tests the behavior on pre-8 indices
146+
*/
147+
public void testMergingMappingsBefore8() throws Exception {
141148
String enabledMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
142149
.startObject("_field_names").field("enabled", true).endObject()
143150
.endObject().endObject());
144151
String disabledMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
145152
.startObject("_field_names").field("enabled", false).endObject()
146153
.endObject().endObject());
147-
MapperService mapperService = createIndex("test").mapperService();
154+
MapperService mapperService = createIndex("test", Settings.builder()
155+
.put(IndexMetaData.SETTING_INDEX_VERSION_CREATED.getKey(),
156+
VersionUtils.randomPreviousCompatibleVersion(random(), Version.V_8_0_0))
157+
.build()).mapperService();
148158

149159
DocumentMapper mapperEnabled = mapperService.merge("type", new CompressedXContent(enabledMapping),
150160
MapperService.MergeReason.MAPPING_UPDATE);
@@ -156,4 +166,12 @@ public void testMergingMappings() throws Exception {
156166
assertTrue(mapperEnabled.metadataMapper(FieldNamesFieldMapper.class).fieldType().isEnabled());
157167
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", "test"));
158168
}
169+
170+
@Override
171+
protected boolean forbidPrivateIndexSettings() {
172+
/**
173+
* This is needed to force the index version with {@link IndexMetaData.SETTING_INDEX_VERSION_CREATED}.
174+
*/
175+
return false;
176+
}
159177
}

server/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,13 @@
5050
import org.apache.lucene.util.automaton.Automaton;
5151
import org.apache.lucene.util.automaton.Operations;
5252
import org.apache.lucene.util.automaton.TooComplexToDeterminizeException;
53-
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
5453
import org.elasticsearch.cluster.metadata.IndexMetaData;
5554
import org.elasticsearch.common.Strings;
5655
import org.elasticsearch.common.compress.CompressedXContent;
5756
import org.elasticsearch.common.settings.Settings;
5857
import org.elasticsearch.common.unit.Fuzziness;
5958
import org.elasticsearch.common.xcontent.XContentBuilder;
6059
import org.elasticsearch.common.xcontent.json.JsonXContent;
61-
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
6260
import org.elasticsearch.index.mapper.MapperService;
6361
import org.elasticsearch.index.search.QueryStringQueryParser;
6462
import org.elasticsearch.search.internal.SearchContext;
@@ -1053,36 +1051,6 @@ public void testExistsFieldQuery() throws Exception {
10531051
assertThat(query, equalTo(expected));
10541052
}
10551053

1056-
public void testDisabledFieldNamesField() throws Exception {
1057-
QueryShardContext context = createShardContext();
1058-
context.getMapperService().merge("_doc",
1059-
new CompressedXContent(Strings
1060-
.toString(PutMappingRequest.buildFromSimplifiedDef("_doc",
1061-
"foo",
1062-
"type=text",
1063-
"_field_names",
1064-
"enabled=false"))),
1065-
MapperService.MergeReason.MAPPING_UPDATE);
1066-
1067-
try {
1068-
QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder("foo:*");
1069-
Query query = queryBuilder.toQuery(context);
1070-
Query expected = new WildcardQuery(new Term("foo", "*"));
1071-
assertThat(query, equalTo(expected));
1072-
} finally {
1073-
// restore mappings as they were before
1074-
context.getMapperService().merge("_doc",
1075-
new CompressedXContent(Strings.toString(
1076-
PutMappingRequest.buildFromSimplifiedDef("_doc",
1077-
"foo",
1078-
"type=text",
1079-
"_field_names",
1080-
"enabled=true"))),
1081-
MapperService.MergeReason.MAPPING_UPDATE);
1082-
}
1083-
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", context.index().getName()));
1084-
}
1085-
10861054
public void testFromJson() throws IOException {
10871055
String json =
10881056
"{\n" +

0 commit comments

Comments
 (0)