Automatically upgrade analyzed strings with an analyzer to `text`. #17861
I had stayed away from it until now since the `analyzer` property is supported on analyzed strings but not on analyzed strings. So th list of supported properties for the upgrade has been splitted so that we would still fail the upgrade if setting an analyzer on a not-analyzed string field. See https://discuss.elastic.co/t/es5-0a1-the-string-type-is-removed-in-5-0-you-should-now-use-either-a-text-or-keyword-field-instead-for-field/47305/7
This commit is contained in:
parent
6921712847
commit
f245fc1ccd
|
@ -70,11 +70,16 @@ public class StringFieldMapper extends FieldMapper implements AllFieldMapper.Inc
|
|||
// If a string field is created on 5.x and all parameters are in this list then we
|
||||
// will automatically upgrade to a text/keyword field. Otherwise we will just fail
|
||||
// saying that string fields are not supported anymore.
|
||||
private static final Set<String> SUPPORTED_PARAMETERS_FOR_AUTO_UPGRADE = new HashSet<>(Arrays.asList(
|
||||
private static final Set<String> SUPPORTED_PARAMETERS_FOR_AUTO_UPGRADE_TO_KEYWORD = new HashSet<>(Arrays.asList(
|
||||
"type",
|
||||
// most common parameters, for which the upgrade is straightforward
|
||||
// common keyword parameters, for which the upgrade is straightforward
|
||||
"index", "store", "doc_values", "omit_norms", "norms", "fields", "copy_to",
|
||||
"fielddata", "ignore_above"));
|
||||
private static final Set<String> SUPPORTED_PARAMETERS_FOR_AUTO_UPGRADE_TO_TEXT = new HashSet<>(Arrays.asList(
|
||||
"type",
|
||||
// common text parameters, for which the upgrade is straightforward
|
||||
"index", "store", "doc_values", "omit_norms", "norms", "fields", "copy_to",
|
||||
"fielddata", "analyzer", "search_analyzer", "search_quote_analyzer"));
|
||||
|
||||
public static class Defaults {
|
||||
public static double FIELDDATA_MIN_FREQUENCY = 0;
|
||||
|
@ -198,12 +203,16 @@ public class StringFieldMapper extends FieldMapper implements AllFieldMapper.Inc
|
|||
@Override
|
||||
public Mapper.Builder parse(String fieldName, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
if (parserContext.indexVersionCreated().onOrAfter(Version.V_5_0_0_alpha1)) {
|
||||
final Object index = node.get("index");
|
||||
final boolean keyword = index != null && "analyzed".equals(index) == false;
|
||||
|
||||
// Automatically upgrade simple mappings for ease of upgrade, otherwise fail
|
||||
if (SUPPORTED_PARAMETERS_FOR_AUTO_UPGRADE.containsAll(node.keySet())) {
|
||||
Set<String> autoUpgradeParameters = keyword
|
||||
? SUPPORTED_PARAMETERS_FOR_AUTO_UPGRADE_TO_KEYWORD
|
||||
: SUPPORTED_PARAMETERS_FOR_AUTO_UPGRADE_TO_TEXT;
|
||||
if (autoUpgradeParameters.containsAll(node.keySet())) {
|
||||
deprecationLogger.deprecated("The [string] field is deprecated, please use [text] or [keyword] instead on [{}]",
|
||||
fieldName);
|
||||
final Object index = node.remove("index");
|
||||
final boolean keyword = index != null && "analyzed".equals(index) == false;
|
||||
{
|
||||
// upgrade the index setting
|
||||
node.put("index", "no".equals(index) == false);
|
||||
|
@ -254,7 +263,7 @@ public class StringFieldMapper extends FieldMapper implements AllFieldMapper.Inc
|
|||
throw new IllegalArgumentException("The [string] type is removed in 5.0. You should now use either a [text] "
|
||||
+ "or [keyword] field instead for field [" + fieldName + "]");
|
||||
}
|
||||
|
||||
|
||||
StringFieldMapper.Builder builder = new StringFieldMapper.Builder(fieldName);
|
||||
// hack for the fact that string can't just accept true/false for
|
||||
// the index property and still accepts no/not_analyzed/analyzed
|
||||
|
|
|
@ -107,7 +107,8 @@ public class StringMappingUpgradeTests extends ESSingleNodeTestCase {
|
|||
IndexService indexService = createIndex("test");
|
||||
DocumentMapperParser parser = indexService.mapperService().documentMapperParser();
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties").startObject("field").field("type", "string").field("analyzer", "keyword").endObject().endObject()
|
||||
.startObject("properties").startObject("field").field("type", "string")
|
||||
.field("index", "not_analyzed").field("analyzer", "keyword").endObject().endObject()
|
||||
.endObject().endObject().string();
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||
() -> parser.parse("type", new CompressedXContent(mapping)));
|
||||
|
@ -164,6 +165,23 @@ public class StringMappingUpgradeTests extends ESSingleNodeTestCase {
|
|||
assertEquals(200, ((KeywordFieldMapper) field).ignoreAbove());
|
||||
}
|
||||
|
||||
public void testUpgradeAnalyzer() throws IOException {
|
||||
IndexService indexService = createIndex("test");
|
||||
DocumentMapperParser parser = indexService.mapperService().documentMapperParser();
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties").startObject("field").field("type", "string")
|
||||
.field("analyzer", "standard")
|
||||
.field("search_analyzer", "whitespace")
|
||||
.field("search_quote_analyzer", "keyword").endObject().endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping));
|
||||
FieldMapper field = mapper.mappers().getMapper("field");
|
||||
assertThat(field, instanceOf(TextFieldMapper.class));
|
||||
assertEquals("standard", field.fieldType().indexAnalyzer().name());
|
||||
assertEquals("whitespace", field.fieldType().searchAnalyzer().name());
|
||||
assertEquals("keyword", field.fieldType().searchQuoteAnalyzer().name());
|
||||
}
|
||||
|
||||
public void testUpgradeRandomMapping() throws IOException {
|
||||
final int iters = 20;
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
|
@ -200,6 +218,9 @@ public class StringMappingUpgradeTests extends ESSingleNodeTestCase {
|
|||
if (keyword && randomBoolean()) {
|
||||
mapping.field("doc_values", randomBoolean());
|
||||
}
|
||||
if (keyword == false && randomBoolean()) {
|
||||
mapping.field("analyzer", "keyword");
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
hasNorms = randomBoolean();
|
||||
if (randomBoolean()) {
|
||||
|
|
Loading…
Reference in New Issue