Browse Source

Always Emit Inference ID in Semantic Text Mapping (#117294) (#117345)

Mike Pellegrini 10 months ago
parent
commit
cabc3a16f1

+ 5 - 0
docs/changelog/117294.yaml

@@ -0,0 +1,5 @@
+pr: 117294
+summary: Always Emit Inference ID in Semantic Text Mapping
+area: Mapping
+type: bug
+issues: []

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

@@ -37,7 +37,8 @@ public class InferenceFeatures implements FeatureSpecification {
             SemanticTextFieldMapper.SEMANTIC_TEXT_IN_OBJECT_FIELD_FIX,
             SemanticTextFieldMapper.SEMANTIC_TEXT_SINGLE_FIELD_UPDATE_FIX,
             SemanticTextFieldMapper.SEMANTIC_TEXT_DELETE_FIX,
-            SemanticTextFieldMapper.SEMANTIC_TEXT_ZERO_SIZE_FIX
+            SemanticTextFieldMapper.SEMANTIC_TEXT_ZERO_SIZE_FIX,
+            SemanticTextFieldMapper.SEMANTIC_TEXT_ALWAYS_EMIT_INFERENCE_ID_FIX
         );
     }
 }

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

@@ -93,6 +93,9 @@ public class SemanticTextFieldMapper extends FieldMapper implements InferenceFie
     public static final NodeFeature SEMANTIC_TEXT_SINGLE_FIELD_UPDATE_FIX = new NodeFeature("semantic_text.single_field_update_fix");
     public static final NodeFeature SEMANTIC_TEXT_DELETE_FIX = new NodeFeature("semantic_text.delete_fix");
     public static final NodeFeature SEMANTIC_TEXT_ZERO_SIZE_FIX = new NodeFeature("semantic_text.zero_size_fix");
+    public static final NodeFeature SEMANTIC_TEXT_ALWAYS_EMIT_INFERENCE_ID_FIX = new NodeFeature(
+        "semantic_text.always_emit_inference_id_fix"
+    );
 
     public static final String CONTENT_TYPE = "semantic_text";
     public static final String DEFAULT_ELSER_2_INFERENCE_ID = DEFAULT_ELSER_ID;
@@ -119,7 +122,7 @@ public class SemanticTextFieldMapper extends FieldMapper implements InferenceFie
                     "[" + INFERENCE_ID_FIELD + "] on mapper [" + leafName() + "] of type [" + CONTENT_TYPE + "] must not be empty"
                 );
             }
-        });
+        }).alwaysSerialize();
 
         private final Parameter<String> searchInferenceId = Parameter.stringParam(
             SEARCH_INFERENCE_ID_FIELD,

+ 14 - 2
x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapperTests.java

@@ -109,6 +109,12 @@ public class SemanticTextFieldMapperTests extends MapperTestCase {
         return "cannot have nested fields when index is in [index.mode=time_series]";
     }
 
+    @Override
+    protected void metaMapping(XContentBuilder b) throws IOException {
+        super.metaMapping(b);
+        b.field(INFERENCE_ID_FIELD, DEFAULT_ELSER_2_INFERENCE_ID);
+    }
+
     @Override
     protected Object getSampleValueForDocument() {
         return null;
@@ -166,10 +172,11 @@ public class SemanticTextFieldMapperTests extends MapperTestCase {
     public void testDefaults() throws Exception {
         final String fieldName = "field";
         final XContentBuilder fieldMapping = fieldMapping(this::minimalMapping);
+        final XContentBuilder expectedMapping = fieldMapping(this::metaMapping);
 
         MapperService mapperService = createMapperService(fieldMapping);
         DocumentMapper mapper = mapperService.documentMapper();
-        assertEquals(Strings.toString(fieldMapping), mapper.mappingSource().toString());
+        assertEquals(Strings.toString(expectedMapping), mapper.mappingSource().toString());
         assertSemanticTextField(mapperService, fieldName, false);
         assertInferenceEndpoints(mapperService, fieldName, DEFAULT_ELSER_2_INFERENCE_ID, DEFAULT_ELSER_2_INFERENCE_ID);
 
@@ -208,10 +215,15 @@ public class SemanticTextFieldMapperTests extends MapperTestCase {
             final XContentBuilder fieldMapping = fieldMapping(
                 b -> b.field("type", "semantic_text").field(SEARCH_INFERENCE_ID_FIELD, searchInferenceId)
             );
+            final XContentBuilder expectedMapping = fieldMapping(
+                b -> b.field("type", "semantic_text")
+                    .field(INFERENCE_ID_FIELD, DEFAULT_ELSER_2_INFERENCE_ID)
+                    .field(SEARCH_INFERENCE_ID_FIELD, searchInferenceId)
+            );
             final MapperService mapperService = createMapperService(fieldMapping);
             assertSemanticTextField(mapperService, fieldName, false);
             assertInferenceEndpoints(mapperService, fieldName, DEFAULT_ELSER_2_INFERENCE_ID, searchInferenceId);
-            assertSerialization.accept(fieldMapping, mapperService);
+            assertSerialization.accept(expectedMapping, mapperService);
         }
         {
             final XContentBuilder fieldMapping = fieldMapping(

+ 26 - 0
x-pack/plugin/inference/src/yamlRestTest/resources/rest-api-spec/test/inference/10_semantic_text_field_mapping.yml

@@ -371,3 +371,29 @@ setup:
   - match: { error.type: illegal_argument_exception }
   - match: { error.reason: "semantic_text field [level_1.level_2.sparse_field] cannot be in an object field with
                             subobjects disabled" }
+
+---
+"Mapping always includes inference ID":
+  - requires:
+      cluster_features: "semantic_text.always_emit_inference_id_fix"
+      reason: always emit inference ID fix added in 8.17.0
+      test_runner_features: [capabilities]
+      capabilities:
+        - method: GET
+          path: /_inference
+          capabilities: [default_elser_2]
+
+  - do:
+      indices.create:
+        index: test-always-include-inference-id-index
+        body:
+          mappings:
+            properties:
+              semantic_field:
+                type: semantic_text
+
+  - do:
+      indices.get_mapping:
+        index: test-always-include-inference-id-index
+
+  - exists: test-always-include-inference-id-index.mappings.properties.semantic_field.inference_id