Skip to content

Commit

Permalink
Support fetching _tier field value (#71379)
Browse files Browse the repository at this point in the history
Now that the `fields` option allows fetching metadata fields, we can support
loading the new `_tier` metadata field.

Relates to #63569 and #68135.
  • Loading branch information
jtibshirani authored Apr 8, 2021
1 parent 5baabff commit 3da738e
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 16 deletions.
13 changes: 6 additions & 7 deletions docs/reference/mapping/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ fields can be customized when a mapping is created.

The index to which the document belongs.

<<mapping-tier-field,`_tier`>>::

The current data tier preference of the index to which the document belongs.


<<mapping-id-field,`_id`>>::

The document's ID.
Expand Down Expand Up @@ -67,6 +62,10 @@ fields can be customized when a mapping is created.

Application specific metadata.

<<mapping-tier-field,`_tier`>>::

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[]
Expand All @@ -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[]
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {

Expand Down Expand Up @@ -52,28 +54,50 @@ 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();
}

@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();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@
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;
import java.util.Arrays;
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 {
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit 3da738e

Please sign in to comment.