Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow _field_names enabled setting #46681

Merged
merged 5 commits into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
24 changes: 4 additions & 20 deletions docs/reference/mapping/fields/field-names-field.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,8 @@ be available but will not use the `_field_names` field.
[[disable-field-names]]
==== Disabling `_field_names`

NOTE: Disabling `_field_names` has been deprecated and will be removed in a future major version.
Disabling `_field_names` is usually no longer possible. It is enabled by default because it no longer
cbuescher marked this conversation as resolved.
Show resolved Hide resolved
carries the index overhead it once did.

Disabling `_field_names` is usually not necessary because it no longer
carries the index overhead it once did. If you have a lot of fields
which have `doc_values` and `norms` disabled and you do not need to
execute `exists` queries using those fields you might want to disable
`_field_names` by adding the following to the mappings:

[source,console]
--------------------------------------------------
PUT tweets
{
"mappings": {
"_field_names": {
"enabled": false
}
}
}
--------------------------------------------------
// CONSOLE
// 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.]
NOTE: Support for disabling `_field_names` has been removed. Using it on new indices will throw an error. Using it in
pre-8.0 indices is still allowed but issues a deprecation warning.
10 changes: 9 additions & 1 deletion docs/reference/migration/migrate_8_0/mappings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,12 @@ Previously, it was possible to define a multi-field within a multi-field.
Defining chained multi-fields was deprecated in 7.3 and is now no longer
supported. To migrate the mappings, all instances of `fields` that occur within
a `fields` block should be removed, either by flattening the chained `fields`
blocks into a single level, or by switching to `copy_to` if appropriate.
blocks into a single level, or by switching to `copy_to` if appropriate.

[float]
==== Disallow use of the `enabled` setting on the `_field_names` field

The setting has been deprecated with 7.5 and is no longer supported on new indices.
Mappings for older indices will continue to work but emit a deprecation warning.
The `enabled` setting for `_field_names` should be removed from templates and mappings.
Disabling _field_names is not necessary because it no longer carries a large index overhead.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.search.Query;
import org.elasticsearch.Version;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.settings.Settings;
Expand All @@ -47,8 +48,7 @@
*/
public class FieldNamesFieldMapper extends MetadataFieldMapper {

private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
LogManager.getLogger(FieldNamesFieldMapper.class));
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(FieldNamesFieldMapper.class));

public static final String NAME = "_field_names";

Expand Down Expand Up @@ -111,8 +111,13 @@ public MetadataFieldMapper.Builder<?,?> parse(String name, Map<String, Object> n
Object fieldNode = entry.getValue();
if (fieldName.equals("enabled")) {
String indexName = parserContext.mapperService().index().getName();
deprecationLogger.deprecatedAndMaybeLog("field_names_enabled_parameter", ENABLED_DEPRECATION_MESSAGE, indexName);
builder.enabled(XContentMapValues.nodeBooleanValue(fieldNode, name + ".enabled"));
if (parserContext.indexVersionCreated().onOrAfter(Version.V_8_0_0)) {
throw new MapperParsingException("The `enabled` setting for the `_field_names` has been deprecated and removed but"
cbuescher marked this conversation as resolved.
Show resolved Hide resolved
+ "is still used in index [{}]. Please remove it from your mappings and templates.");
} else {
deprecationLogger.deprecatedAndMaybeLog("field_names_enabled_parameter", ENABLED_DEPRECATION_MESSAGE, indexName);
builder.enabled(XContentMapValues.nodeBooleanValue(fieldNode, name + ".enabled"));
}
iterator.remove();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@
package org.elasticsearch.index.mapper;

import org.apache.lucene.index.IndexOptions;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.elasticsearch.test.VersionUtils;

import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -95,33 +99,33 @@ public void testInjectIntoDocDuringParsing() throws Exception {
assertFieldNames(Collections.emptySet(), doc);
}

public void testExplicitEnabled() throws Exception {
public void testUsingEnabledSettingThrows() throws Exception {
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_field_names").field("enabled", true).endObject()
.startObject("properties")
.startObject("field").field("type", "keyword").field("doc_values", false).endObject()
.endObject().endObject().endObject());
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser()
.parse("type", new CompressedXContent(mapping));
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertTrue(fieldNamesMapper.fieldType().isEnabled());
MapperParsingException ex = expectThrows(MapperParsingException.class, () -> createIndex("test").mapperService().documentMapperParser()
.parse("type", new CompressedXContent(mapping)));

ParsedDocument doc = docMapper.parse(new SourceToParse("test", "type", "1",
BytesReference.bytes(XContentFactory.jsonBuilder()
.startObject()
.field("field", "value")
.endObject()),
XContentType.JSON));

assertFieldNames(set("field"), doc);
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", "test"));
assertEquals("The `enabled` setting for the `_field_names` has been deprecated and removed butis still used in index [{}]. "
cbuescher marked this conversation as resolved.
Show resolved Hide resolved
+ "Please remove it from your mappings and templates.", ex.getMessage());
}

public void testDisabled() throws Exception {
/**
* disabling the _field_names should still work for indices before 8.0
*/
public void testUsingEnabledBefore8() throws Exception {
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_field_names").field("enabled", false).endObject()
.endObject().endObject());
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser()

DocumentMapper docMapper = createIndex("test",
Settings.builder()
.put(IndexMetaData.SETTING_INDEX_VERSION_CREATED.getKey(),
VersionUtils.randomPreviousCompatibleVersion(random(), Version.V_8_0_0))
.build()).mapperService()
.documentMapperParser()
.parse("type", new CompressedXContent(mapping));
FieldNamesFieldMapper fieldNamesMapper = docMapper.metadataMapper(FieldNamesFieldMapper.class);
assertFalse(fieldNamesMapper.fieldType().isEnabled());
Expand All @@ -137,14 +141,20 @@ public void testDisabled() throws Exception {
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", "test"));
}

public void testMergingMappings() throws Exception {
/**
* Merging the "_field_names" enabled setting is forbidden in 8.0, but we still want to tests the behavior on pre-8 indices
*/
public void testMergingMappingsBefore8() throws Exception {
String enabledMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_field_names").field("enabled", true).endObject()
.endObject().endObject());
String disabledMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_field_names").field("enabled", false).endObject()
.endObject().endObject());
MapperService mapperService = createIndex("test").mapperService();
MapperService mapperService = createIndex("test", Settings.builder()
.put(IndexMetaData.SETTING_INDEX_VERSION_CREATED.getKey(),
VersionUtils.randomPreviousCompatibleVersion(random(), Version.V_8_0_0))
.build()).mapperService();

DocumentMapper mapperEnabled = mapperService.merge("type", new CompressedXContent(enabledMapping),
MapperService.MergeReason.MAPPING_UPDATE);
Expand All @@ -156,4 +166,12 @@ public void testMergingMappings() throws Exception {
assertTrue(mapperEnabled.metadataMapper(FieldNamesFieldMapper.class).fieldType().isEnabled());
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", "test"));
}

@Override
protected boolean forbidPrivateIndexSettings() {
/**
* This is needed to force the index version with {@link IndexMetaData.SETTING_INDEX_VERSION_CREATED}.
*/
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,13 @@
import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.Operations;
import org.apache.lucene.util.automaton.TooComplexToDeterminizeException;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.search.QueryStringQueryParser;
import org.elasticsearch.search.internal.SearchContext;
Expand Down Expand Up @@ -1053,36 +1051,6 @@ public void testExistsFieldQuery() throws Exception {
assertThat(query, equalTo(expected));
}

public void testDisabledFieldNamesField() throws Exception {
QueryShardContext context = createShardContext();
context.getMapperService().merge("_doc",
new CompressedXContent(Strings
.toString(PutMappingRequest.buildFromSimplifiedDef("_doc",
"foo",
"type=text",
"_field_names",
"enabled=false"))),
MapperService.MergeReason.MAPPING_UPDATE);

try {
QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder("foo:*");
Query query = queryBuilder.toQuery(context);
Query expected = new WildcardQuery(new Term("foo", "*"));
assertThat(query, equalTo(expected));
} finally {
// restore mappings as they were before
context.getMapperService().merge("_doc",
new CompressedXContent(Strings.toString(
PutMappingRequest.buildFromSimplifiedDef("_doc",
"foo",
"type=text",
"_field_names",
"enabled=true"))),
MapperService.MergeReason.MAPPING_UPDATE);
}
assertWarnings(FieldNamesFieldMapper.TypeParser.ENABLED_DEPRECATION_MESSAGE.replace("{}", context.index().getName()));
}

public void testFromJson() throws IOException {
String json =
"{\n" +
Expand Down