Skip to content

Commit 4205b04

Browse files
committed
Support fetching _tier field value (#71379)
Now that the `fields` option allows fetching metadata fields, we can support loading the new `_tier` metadata field. Relates to #63569 and #68135.
1 parent 88e4fac commit 4205b04

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

docs/reference/mapping/fields.asciidoc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ some of these metadata fields can be customized when a mapping type is created.
1717

1818
The document's mapping type.
1919

20-
<<mapping-tier-field,`_tier`>>::
21-
22-
The current data tier preference of the index to which the document belongs.
23-
2420
<<mapping-id-field,`_id`>>::
2521

2622
The document's ID.
@@ -70,6 +66,10 @@ some of these metadata fields can be customized when a mapping type is created.
7066

7167
Application specific metadata.
7268

69+
<<mapping-tier-field,`_tier`>>::
70+
71+
The current data tier preference of the index to which the document belongs.
72+
7373
include::fields/doc-count-field.asciidoc[]
7474

7575
include::fields/field-names-field.asciidoc[]
@@ -80,13 +80,12 @@ include::fields/id-field.asciidoc[]
8080

8181
include::fields/index-field.asciidoc[]
8282

83-
include::fields/tier-field.asciidoc[]
84-
8583
include::fields/meta-field.asciidoc[]
8684

8785
include::fields/routing-field.asciidoc[]
8886

8987
include::fields/source-field.asciidoc[]
9088

91-
include::fields/type-field.asciidoc[]
89+
include::fields/tier-field.asciidoc[]
9290

91+
include::fields/type-field.asciidoc[]

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldMapper.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.apache.lucene.search.Query;
1313
import org.elasticsearch.common.Strings;
1414
import org.elasticsearch.common.regex.Regex;
15+
import org.elasticsearch.common.settings.Settings;
1516
import org.elasticsearch.index.mapper.ConstantFieldType;
1617
import org.elasticsearch.index.mapper.KeywordFieldMapper;
1718
import org.elasticsearch.index.mapper.MetadataFieldMapper;
@@ -52,28 +53,50 @@ protected boolean matches(String pattern, boolean caseInsensitive, SearchExecuti
5253
if (caseInsensitive) {
5354
pattern = Strings.toLowercaseAscii(pattern);
5455
}
55-
String tierPreference = DataTierAllocationDecider.INDEX_ROUTING_PREFER_SETTING.get(context.getIndexSettings().getSettings());
56-
if (Strings.hasText(tierPreference) == false) {
56+
57+
String tierPreference = getTierPreference(context);
58+
if (tierPreference == null) {
5759
return false;
5860
}
59-
// Tier preference can be a comma-delimited list of tiers, ordered by preference
60-
// It was decided we should only test the first of these potentially multiple preferences.
61-
String firstPreference = tierPreference.split(",")[0].trim();
62-
return Regex.simpleMatch(pattern, firstPreference);
61+
return Regex.simpleMatch(pattern, tierPreference);
6362
}
6463

6564
@Override
6665
public Query existsQuery(SearchExecutionContext context) {
67-
String tierPreference = DataTierAllocationDecider.INDEX_ROUTING_PREFER_SETTING.get(context.getIndexSettings().getSettings());
68-
if (Strings.hasText(tierPreference) == false) {
66+
String tierPreference = getTierPreference(context);
67+
if (tierPreference == null) {
6968
return new MatchNoDocsQuery();
7069
}
7170
return new MatchAllDocsQuery();
7271
}
7372

7473
@Override
7574
public ValueFetcher valueFetcher(SearchExecutionContext context, String format) {
76-
throw new UnsupportedOperationException("Cannot fetch values for internal field [" + name() + "].");
75+
if (format != null) {
76+
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
77+
}
78+
79+
String tierPreference = getTierPreference(context);
80+
return tierPreference == null
81+
? lookup -> Collections.emptyList()
82+
: lookup -> Collections.singletonList(tierPreference);
83+
}
84+
85+
/**
86+
* Retrieve the first tier preference from the index setting. If the setting is not
87+
* present, then return null.
88+
*/
89+
private String getTierPreference(SearchExecutionContext context) {
90+
Settings settings = context.getIndexSettings().getSettings();
91+
String value = DataTierAllocationDecider.INDEX_ROUTING_PREFER_SETTING.get(settings);
92+
93+
if (Strings.hasText(value) == false) {
94+
return null;
95+
}
96+
97+
// Tier preference can be a comma-delimited list of tiers, ordered by preference
98+
// It was decided we should only test the first of these potentially multiple preferences.
99+
return value.split(",")[0].trim();
77100
}
78101
}
79102

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/mapper/DataTierFieldTypeTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@
1616
import org.elasticsearch.index.IndexSettings;
1717
import org.elasticsearch.index.mapper.MappedFieldType;
1818
import org.elasticsearch.index.mapper.MapperServiceTestCase;
19+
import org.elasticsearch.index.mapper.ValueFetcher;
1920
import org.elasticsearch.index.query.QueryShardException;
2021
import org.elasticsearch.index.query.SearchExecutionContext;
22+
import org.elasticsearch.search.lookup.SourceLookup;
2123
import org.elasticsearch.xpack.cluster.routing.allocation.DataTierAllocationDecider;
2224

2325
import java.io.IOException;
2426
import java.util.Arrays;
2527
import java.util.function.Predicate;
2628

2729
import static java.util.Collections.emptyMap;
30+
import static java.util.Collections.singletonList;
2831
import static org.hamcrest.Matchers.containsString;
2932

3033
public class DataTierFieldTypeTests extends MapperServiceTestCase {
@@ -81,6 +84,17 @@ public void testRegexpQuery() {
8184
assertThat(e.getMessage(), containsString("Can only use regexp queries on keyword and text fields"));
8285
}
8386

87+
public void testFetchValue() throws IOException {
88+
MappedFieldType ft = DataTierFieldMapper.DataTierFieldType.INSTANCE;
89+
SourceLookup lookup = new SourceLookup();
90+
91+
ValueFetcher valueFetcher = ft.valueFetcher(createContext(), null);
92+
assertEquals(singletonList("data_warm"), valueFetcher.fetchValues(lookup));
93+
94+
ValueFetcher emptyValueFetcher = ft.valueFetcher(createContextWithoutSetting(), null);
95+
assertTrue(emptyValueFetcher.fetchValues(lookup).isEmpty());
96+
}
97+
8498
private SearchExecutionContext createContext() {
8599
IndexMetadata indexMetadata = IndexMetadata.builder("index")
86100
.settings(

0 commit comments

Comments
 (0)