Skip to content

Commit e54acc3

Browse files
Fix - Requesting _inference_fields when using legacy format causes shard failure (#121720) (#122177)
* Adding condition to verify if the field belongs to an index * Update docs/changelog/121720.yaml * Remove unnecessary comma from yaml file * remove duplicate inference endpoint creation * updating isMetadata to return true if mapper has the correct type * remove unnecessary index creation in yaml tests * Adding check if the document has returned in the yaml test * Updating test to skip time series check if index mode is standard * Refactor tests to consider verifying every metafields with all index modes * refactoring test to verify for all cases * Adding assetFalse if not time_series and fields are from time_series * updating test texts to have better description
1 parent 8854117 commit e54acc3

File tree

6 files changed

+85
-8
lines changed

6 files changed

+85
-8
lines changed

docs/changelog/121720.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 121720
2+
summary: Skip fetching _inference_fields field in legacy semantic_text format
3+
area: Search
4+
type: bug
5+
issues: []

server/src/main/java/org/elasticsearch/index/mapper/MapperService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,8 @@ public static boolean isMetadataFieldStatic(String fieldName) {
801801
* this method considers all mapper plugins
802802
*/
803803
public boolean isMetadataField(String field) {
804-
return mapperRegistry.getMetadataMapperParsers(indexVersionCreated).containsKey(field);
804+
var mapper = mappingLookup().getMapper(field);
805+
return mapper instanceof MetadataFieldMapper;
805806
}
806807

807808
/**

server/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
import org.elasticsearch.common.bytes.BytesReference;
1616
import org.elasticsearch.common.compress.CompressedXContent;
1717
import org.elasticsearch.common.settings.Settings;
18+
import org.elasticsearch.core.CheckedFunction;
19+
import org.elasticsearch.index.IndexMode;
20+
import org.elasticsearch.index.IndexSettings;
1821
import org.elasticsearch.index.IndexVersion;
1922
import org.elasticsearch.index.IndexVersions;
2023
import org.elasticsearch.index.mapper.MapperService.MergeReason;
@@ -26,6 +29,7 @@
2629
import java.io.IOException;
2730
import java.util.List;
2831
import java.util.Map;
32+
import java.util.function.Consumer;
2933
import java.util.function.Function;
3034
import java.util.stream.Collectors;
3135
import java.util.stream.StreamSupport;
@@ -304,16 +308,56 @@ public void testMappingRecoverySkipFieldNameLengthLimit() throws Throwable {
304308

305309
public void testIsMetadataField() throws IOException {
306310
IndexVersion version = IndexVersionUtils.randomCompatibleVersion(random());
307-
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
308311

309-
MapperService mapperService = createMapperService(settings, mapping(b -> {}));
310-
assertFalse(mapperService.isMetadataField(randomAlphaOfLengthBetween(10, 15)));
312+
CheckedFunction<IndexMode, MapperService, IOException> initMapperService = (indexMode) -> {
313+
Settings.Builder settingsBuilder = Settings.builder()
314+
.put(IndexMetadata.SETTING_VERSION_CREATED, version)
315+
.put(IndexSettings.MODE.getKey(), indexMode);
311316

312-
for (String builtIn : IndicesModule.getBuiltInMetadataFields()) {
313-
if (NestedPathFieldMapper.NAME.equals(builtIn) && version.before(IndexVersions.V_8_0_0)) {
314-
continue; // Nested field does not exist in the 7x line
317+
if (indexMode == IndexMode.TIME_SERIES) {
318+
settingsBuilder.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "foo");
315319
}
316-
assertTrue("Expected " + builtIn + " to be a metadata field for version " + version, mapperService.isMetadataField(builtIn));
320+
321+
return createMapperService(settingsBuilder.build(), mapping(b -> {}));
322+
};
323+
324+
Consumer<MapperService> assertMapperService = (mapperService) -> {
325+
assertFalse(mapperService.isMetadataField(randomAlphaOfLengthBetween(10, 15)));
326+
327+
for (String builtIn : IndicesModule.getBuiltInMetadataFields()) {
328+
if (NestedPathFieldMapper.NAME.equals(builtIn) && version.before(IndexVersions.V_8_0_0)) {
329+
continue; // Nested field does not exist in the 7x line
330+
}
331+
boolean isTimeSeriesField = builtIn.equals("_tsid") || builtIn.equals("_ts_routing_hash");
332+
boolean isTimeSeriesMode = mapperService.getIndexSettings().getMode().equals(IndexMode.TIME_SERIES);
333+
334+
if (isTimeSeriesField && isTimeSeriesMode == false) {
335+
assertFalse(
336+
"Expected "
337+
+ builtIn
338+
+ " to not be a metadata field for version "
339+
+ version
340+
+ " and index mode "
341+
+ mapperService.getIndexSettings().getMode(),
342+
mapperService.isMetadataField(builtIn)
343+
);
344+
} else {
345+
assertTrue(
346+
"Expected "
347+
+ builtIn
348+
+ " to be a metadata field for version "
349+
+ version
350+
+ " and index mode "
351+
+ mapperService.getIndexSettings().getMode(),
352+
mapperService.isMetadataField(builtIn)
353+
);
354+
}
355+
}
356+
};
357+
358+
for (IndexMode indexMode : IndexMode.values()) {
359+
MapperService mapperService = initMapperService.apply(indexMode);
360+
assertMapperService.accept(mapperService);
317361
}
318362
}
319363

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceFeatures.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public Set<NodeFeature> getTestFeatures() {
3636
SemanticTextFieldMapper.SEMANTIC_TEXT_DELETE_FIX,
3737
SemanticTextFieldMapper.SEMANTIC_TEXT_ZERO_SIZE_FIX,
3838
SemanticTextFieldMapper.SEMANTIC_TEXT_ALWAYS_EMIT_INFERENCE_ID_FIX,
39+
SemanticTextFieldMapper.SEMANTIC_TEXT_SKIP_INFERENCE_FIELDS,
3940
SEMANTIC_TEXT_HIGHLIGHTER,
4041
SEMANTIC_MATCH_QUERY_REWRITE_INTERCEPTION_SUPPORTED,
4142
SEMANTIC_SPARSE_VECTOR_QUERY_REWRITE_INTERCEPTION_SUPPORTED,

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ public class SemanticTextFieldMapper extends FieldMapper implements InferenceFie
117117
public static final NodeFeature SEMANTIC_TEXT_ALWAYS_EMIT_INFERENCE_ID_FIX = new NodeFeature(
118118
"semantic_text.always_emit_inference_id_fix"
119119
);
120+
public static final NodeFeature SEMANTIC_TEXT_SKIP_INFERENCE_FIELDS = new NodeFeature("semantic_text.skip_inference_fields");
120121

121122
public static final String CONTENT_TYPE = "semantic_text";
122123
public static final String DEFAULT_ELSER_2_INFERENCE_ID = DEFAULT_ELSER_ID;

x-pack/plugin/inference/src/yamlRestTest/resources/rest-api-spec/test/inference/30_semantic_text_inference_bwc.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,3 +650,28 @@ setup:
650650
- match: { hits.total.value: 1 }
651651
- match: { hits.total.relation: eq }
652652
- match: { hits.hits.0._source.dense_field.text: "updated text" }
653+
654+
---
655+
"Skip fetching _inference_fields":
656+
- requires:
657+
cluster_features: semantic_text.skip_inference_fields
658+
reason: Skip _inference_fields when search is performed on legacy semantic_text format.
659+
660+
- do:
661+
index:
662+
index: test-index
663+
id: doc_1
664+
body:
665+
sparse_field: "test value"
666+
refresh: true
667+
668+
- do:
669+
search:
670+
index: test-index
671+
body:
672+
fields: [ _inference_fields ]
673+
query:
674+
match_all: { }
675+
676+
- match: { hits.total.value: 1 }
677+
- not_exists: hits.hits.0._source._inference_fields

0 commit comments

Comments
 (0)