diff --git a/docs/reference/mapping/fields.asciidoc b/docs/reference/mapping/fields.asciidoc index 80778ffa906f8..6a2b4d35b9fd6 100644 --- a/docs/reference/mapping/fields.asciidoc +++ b/docs/reference/mapping/fields.asciidoc @@ -13,11 +13,6 @@ fields can be customized when a mapping is created. The index to which the document belongs. -<>:: - - The current data tier preference of the index to which the document belongs. - - <>:: The document's ID. @@ -67,6 +62,10 @@ fields can be customized when a mapping is created. Application specific metadata. +<>:: + + The current data tier preference of the index to which the document belongs. + include::fields/doc-count-field.asciidoc[] include::fields/field-names-field.asciidoc[] @@ -77,10 +76,10 @@ include::fields/id-field.asciidoc[] include::fields/index-field.asciidoc[] -include::fields/tier-field.asciidoc[] - include::fields/meta-field.asciidoc[] include::fields/routing-field.asciidoc[] include::fields/source-field.asciidoc[] + +include::fields/tier-field.asciidoc[] diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldMapper.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldMapper.java index 33324f43b1ff0..45da755e63fd2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldMapper.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldMapper.java @@ -12,6 +12,7 @@ import org.apache.lucene.search.Query; import org.elasticsearch.common.Strings; import org.elasticsearch.common.regex.Regex; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.mapper.ConstantFieldType; import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MetadataFieldMapper; @@ -20,6 +21,7 @@ import org.elasticsearch.xpack.cluster.routing.allocation.DataTierAllocationDecider; import java.util.Collections; +import java.util.List; public class DataTierFieldMapper extends MetadataFieldMapper { @@ -52,20 +54,18 @@ protected boolean matches(String pattern, boolean caseInsensitive, SearchExecuti if (caseInsensitive) { pattern = Strings.toLowercaseAscii(pattern); } - String tierPreference = DataTierAllocationDecider.INDEX_ROUTING_PREFER_SETTING.get(context.getIndexSettings().getSettings()); - if (Strings.hasText(tierPreference) == false) { + + String tierPreference = getTierPreference(context); + if (tierPreference == null) { return false; } - // Tier preference can be a comma-delimited list of tiers, ordered by preference - // It was decided we should only test the first of these potentially multiple preferences. - String firstPreference = tierPreference.split(",")[0].trim(); - return Regex.simpleMatch(pattern, firstPreference); + return Regex.simpleMatch(pattern, tierPreference); } @Override public Query existsQuery(SearchExecutionContext context) { - String tierPreference = DataTierAllocationDecider.INDEX_ROUTING_PREFER_SETTING.get(context.getIndexSettings().getSettings()); - if (Strings.hasText(tierPreference) == false) { + String tierPreference = getTierPreference(context); + if (tierPreference == null) { return new MatchNoDocsQuery(); } return new MatchAllDocsQuery(); @@ -73,7 +73,31 @@ public Query existsQuery(SearchExecutionContext context) { @Override public ValueFetcher valueFetcher(SearchExecutionContext context, String format) { - throw new UnsupportedOperationException("Cannot fetch values for internal field [" + name() + "]."); + if (format != null) { + throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats."); + } + + String tierPreference = getTierPreference(context); + return tierPreference == null + ? lookup -> List.of() + : lookup -> List.of(tierPreference); + } + + /** + * Retrieve the first tier preference from the index setting. If the setting is not + * present, then return null. + */ + private String getTierPreference(SearchExecutionContext context) { + Settings settings = context.getIndexSettings().getSettings(); + String value = DataTierAllocationDecider.INDEX_ROUTING_PREFER_SETTING.get(settings); + + if (Strings.hasText(value) == false) { + return null; + } + + // Tier preference can be a comma-delimited list of tiers, ordered by preference + // It was decided we should only test the first of these potentially multiple preferences. + return value.split(",")[0].trim(); } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldTypeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldTypeTests.java index 298ea5e23e2ec..586e69223dc97 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldTypeTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldTypeTests.java @@ -16,8 +16,10 @@ import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperServiceTestCase; +import org.elasticsearch.index.mapper.ValueFetcher; import org.elasticsearch.index.query.QueryShardException; import org.elasticsearch.index.query.SearchExecutionContext; +import org.elasticsearch.search.lookup.SourceLookup; import org.elasticsearch.xpack.cluster.routing.allocation.DataTierAllocationDecider; import java.io.IOException; @@ -25,6 +27,7 @@ import java.util.function.Predicate; import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonList; import static org.hamcrest.Matchers.containsString; public class DataTierFieldTypeTests extends MapperServiceTestCase { @@ -81,6 +84,17 @@ public void testRegexpQuery() { assertThat(e.getMessage(), containsString("Can only use regexp queries on keyword and text fields")); } + public void testFetchValue() throws IOException { + MappedFieldType ft = DataTierFieldMapper.DataTierFieldType.INSTANCE; + SourceLookup lookup = new SourceLookup(); + + ValueFetcher valueFetcher = ft.valueFetcher(createContext(), null); + assertEquals(singletonList("data_warm"), valueFetcher.fetchValues(lookup)); + + ValueFetcher emptyValueFetcher = ft.valueFetcher(createContextWithoutSetting(), null); + assertTrue(emptyValueFetcher.fetchValues(lookup).isEmpty()); + } + private SearchExecutionContext createContext() { IndexMetadata indexMetadata = IndexMetadata.builder("index") .settings(