3535import org .elasticsearch .common .settings .Settings ;
3636import org .elasticsearch .core .CheckedConsumer ;
3737import org .elasticsearch .index .IndexVersion ;
38+ import org .elasticsearch .index .IndexVersions ;
3839import org .elasticsearch .index .mapper .DocumentMapper ;
3940import org .elasticsearch .index .mapper .DocumentParsingException ;
4041import org .elasticsearch .index .mapper .FieldMapper ;
6465import org .elasticsearch .search .LeafNestedDocuments ;
6566import org .elasticsearch .search .NestedDocuments ;
6667import org .elasticsearch .search .SearchHit ;
68+ import org .elasticsearch .test .index .IndexVersionUtils ;
6769import org .elasticsearch .xcontent .XContentBuilder ;
6870import org .elasticsearch .xcontent .XContentType ;
6971import org .elasticsearch .xcontent .json .JsonXContent ;
@@ -117,16 +119,40 @@ protected Collection<? extends Plugin> getPlugins() {
117119 }
118120
119121 private MapperService createMapperService (XContentBuilder mappings , boolean useLegacyFormat ) throws IOException {
122+ IndexVersion indexVersion = SemanticInferenceMetadataFieldsMapperTests .getRandomCompatibleIndexVersion (useLegacyFormat );
123+ return createMapperService (mappings , useLegacyFormat , indexVersion , indexVersion );
124+ }
125+
126+ private MapperService createMapperService (XContentBuilder mappings , boolean useLegacyFormat , IndexVersion minIndexVersion )
127+ throws IOException {
128+ return createMapperService (mappings , useLegacyFormat , minIndexVersion , IndexVersion .current ());
129+ }
130+
131+ private MapperService createMapperService (
132+ XContentBuilder mappings ,
133+ boolean useLegacyFormat ,
134+ IndexVersion minIndexVersion ,
135+ IndexVersion maxIndexVersion
136+ ) throws IOException {
137+ validateIndexVersion (minIndexVersion , useLegacyFormat );
120138 var settings = Settings .builder ()
121139 .put (
122140 IndexMetadata .SETTING_INDEX_VERSION_CREATED .getKey (),
123- SemanticInferenceMetadataFieldsMapperTests . getRandomCompatibleIndexVersion ( useLegacyFormat )
141+ IndexVersionUtils . randomVersionBetween ( random (), minIndexVersion , maxIndexVersion )
124142 )
125143 .put (InferenceMetadataFieldsMapper .USE_LEGACY_SEMANTIC_TEXT_FORMAT .getKey (), useLegacyFormat )
126144 .build ();
127145 return createMapperService (settings , mappings );
128146 }
129147
148+ private static void validateIndexVersion (IndexVersion indexVersion , boolean useLegacyFormat ) {
149+ if (useLegacyFormat == false
150+ && indexVersion .before (IndexVersions .INFERENCE_METADATA_FIELDS )
151+ && indexVersion .between (IndexVersions .INFERENCE_METADATA_FIELDS_BACKPORT , IndexVersions .UPGRADE_TO_LUCENE_10_0_0 ) == false ) {
152+ throw new IllegalArgumentException ("Index version does not support new semantic text format" );
153+ }
154+ }
155+
130156 @ Override
131157 protected Settings getIndexSettings () {
132158 return Settings .builder ()
@@ -1082,7 +1108,7 @@ public void testDefaultIndexOptions() throws IOException {
10821108 b .field ("similarity" , "cosine" );
10831109 b .field ("element_type" , "float" );
10841110 b .endObject ();
1085- }), useLegacyFormat );
1111+ }), useLegacyFormat , IndexVersions . SEMANTIC_TEXT_DEFAULTS_TO_BBQ );
10861112 assertSemanticTextField (mapperService , "field" , true , null , SemanticTextFieldMapper .defaultSemanticDenseIndexOptions ());
10871113
10881114 // Element types that are incompatible with BBQ will continue to use dense_vector defaults
@@ -1095,7 +1121,7 @@ public void testDefaultIndexOptions() throws IOException {
10951121 b .field ("similarity" , "cosine" );
10961122 b .field ("element_type" , "byte" );
10971123 b .endObject ();
1098- }), useLegacyFormat );
1124+ }), useLegacyFormat , IndexVersions . SEMANTIC_TEXT_DEFAULTS_TO_BBQ );
10991125 assertSemanticTextField (mapperService , "field" , true , null , null );
11001126
11011127 // A dim count of 10 is too small to support BBQ, so we continue to use dense_vector defaults
@@ -1108,9 +1134,26 @@ public void testDefaultIndexOptions() throws IOException {
11081134 b .field ("similarity" , "cosine" );
11091135 b .field ("element_type" , "float" );
11101136 b .endObject ();
1111- }), useLegacyFormat );
1137+ }), useLegacyFormat , IndexVersions . SEMANTIC_TEXT_DEFAULTS_TO_BBQ );
11121138 assertSemanticTextField (mapperService , "field" , true , null , defaultDenseVectorIndexOptions ());
11131139
1140+ // Previous index versions do not set BBQ index options
1141+ mapperService = createMapperService (fieldMapping (b -> {
1142+ b .field ("type" , "semantic_text" );
1143+ b .field ("inference_id" , "another_inference_id" );
1144+ b .startObject ("model_settings" );
1145+ b .field ("task_type" , "text_embedding" );
1146+ b .field ("dimensions" , 100 );
1147+ b .field ("similarity" , "cosine" );
1148+ b .field ("element_type" , "float" );
1149+ b .endObject ();
1150+ }),
1151+ useLegacyFormat ,
1152+ IndexVersions .UPGRADE_TO_LUCENE_10_0_0 ,
1153+ IndexVersionUtils .getPreviousVersion (IndexVersions .SEMANTIC_TEXT_DEFAULTS_TO_BBQ )
1154+ );
1155+ assertSemanticTextField (mapperService , "field" , true , null , SemanticTextFieldMapper .defaultSemanticDenseIndexOptions ());
1156+
11141157 }
11151158
11161159 @ Override
0 commit comments