Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/133080.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 133080
summary: "Disallow creating `semantic_text` fields in indices created prior to 8.11.0"
area: Relevance
type: bug
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import static org.apache.lucene.tests.index.BaseKnnVectorsFormatTestCase.randomNormalizedVector;
import static org.elasticsearch.index.codec.vectors.IVFVectorsFormat.DYNAMIC_NPROBE;
import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.DEFAULT_OVERSAMPLE;
import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.INDEXED_BY_DEFAULT_INDEX_VERSION;
import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.IVF_FORMAT;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
Expand Down Expand Up @@ -107,7 +108,7 @@ private void indexMapping(XContentBuilder b, IndexVersion indexVersion) throws I
if (elementType != ElementType.FLOAT) {
b.field("element_type", elementType.toString());
}
if (indexVersion.onOrAfter(DenseVectorFieldMapper.INDEXED_BY_DEFAULT_INDEX_VERSION) || indexed) {
if (indexVersion.onOrAfter(INDEXED_BY_DEFAULT_INDEX_VERSION) || indexed) {
// Serialize if it's new index version, or it was not the default for previous indices
b.field("index", indexed);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
import java.util.function.Function;
import java.util.function.Supplier;

import static org.elasticsearch.index.IndexVersions.NEW_SPARSE_VECTOR;
import static org.elasticsearch.index.IndexVersions.SEMANTIC_TEXT_DEFAULTS_TO_BBQ;
import static org.elasticsearch.index.IndexVersions.SEMANTIC_TEXT_DEFAULTS_TO_BBQ_BACKPORT_8_X;
import static org.elasticsearch.inference.TaskType.SPARSE_EMBEDDING;
Expand All @@ -124,6 +125,7 @@
*/
public class SemanticTextFieldMapper extends FieldMapper implements InferenceFieldMapper {
private static final Logger logger = LogManager.getLogger(SemanticTextFieldMapper.class);
public static final String UNSUPPORTED_INDEX_MESSAGE = "[semantic_text] is available on indices created with 8.11 or higher.";
public static final NodeFeature SEMANTIC_TEXT_IN_OBJECT_FIELD_FIX = new NodeFeature("semantic_text.in_object_field_fix");
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");
Expand Down Expand Up @@ -156,6 +158,9 @@ public static final TypeParser parser(Supplier<ModelRegistry> modelRegistry) {

public static BiConsumer<String, MappingParserContext> validateParserContext(String type) {
return (n, c) -> {
if (c.getIndexSettings().getIndexVersionCreated().before(NEW_SPARSE_VECTOR)) {
throw new UnsupportedOperationException(UNSUPPORTED_INDEX_MESSAGE);
}
if (InferenceMetadataFieldsMapper.isEnabled(c.getIndexSettings().getSettings()) == false) {
notInMultiFields(type).accept(n, c);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
import static org.elasticsearch.xpack.inference.mapper.SemanticTextFieldMapper.DEFAULT_ELSER_2_INFERENCE_ID;
import static org.elasticsearch.xpack.inference.mapper.SemanticTextFieldMapper.DEFAULT_RESCORE_OVERSAMPLE;
import static org.elasticsearch.xpack.inference.mapper.SemanticTextFieldMapper.INDEX_OPTIONS_FIELD;
import static org.elasticsearch.xpack.inference.mapper.SemanticTextFieldMapper.UNSUPPORTED_INDEX_MESSAGE;
import static org.elasticsearch.xpack.inference.mapper.SemanticTextFieldTests.generateRandomChunkingSettings;
import static org.elasticsearch.xpack.inference.mapper.SemanticTextFieldTests.generateRandomChunkingSettingsOtherThan;
import static org.elasticsearch.xpack.inference.mapper.SemanticTextFieldTests.randomSemanticText;
Expand Down Expand Up @@ -402,6 +403,57 @@ public void testInvalidTaskTypes() {
}
}

@Override
protected IndexVersion boostNotAllowedIndexVersion() {
return IndexVersions.NEW_SPARSE_VECTOR;
}

public void testOldIndexSemanticTextDenseVectorRaisesError() throws IOException {
final String fieldName = "field";
final XContentBuilder fieldMapping = fieldMapping(b -> {
b.field("type", "semantic_text");
b.field(INFERENCE_ID_FIELD, "test_inference_id");
b.startObject("model_settings");
b.field("task_type", "text_embedding");
b.field("dimensions", 384);
b.field("similarity", "cosine");
b.field("element_type", "float");
b.endObject();
});
assertOldIndexUnsupported(fieldMapping);
}

public void testOldIndexSemanticTextMinimalMappingRaisesError() throws IOException {
final XContentBuilder fieldMapping = fieldMapping(this::minimalMapping);
assertOldIndexUnsupported(fieldMapping);
}

public void testOldIndexSemanticTextSparseVersionRaisesError() throws IOException {
final XContentBuilder fieldMapping = fieldMapping(b -> {
b.field("type", "semantic_text");
b.field("inference_id", "another_inference_id");
b.startObject("model_settings");
b.field("task_type", "sparse_embedding");
b.endObject();
});
assertOldIndexUnsupported(fieldMapping);
}

private void assertOldIndexUnsupported(XContentBuilder fieldMapping) {

MapperParsingException exception = assertThrows(
MapperParsingException.class,
() -> createMapperService(
fieldMapping,
true,
IndexVersions.V_8_0_0,
IndexVersionUtils.getPreviousVersion(IndexVersions.NEW_SPARSE_VECTOR)
)
);
assertTrue(exception.getMessage().contains(UNSUPPORTED_INDEX_MESSAGE));
assertTrue(exception.getRootCause() instanceof UnsupportedOperationException);
}

public void testMultiFieldsSupport() throws IOException {
if (useLegacyFormat) {
Exception e = expectThrows(MapperParsingException.class, () -> createMapperService(fieldMapping(b -> {
Expand Down
Loading