diff --git a/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java b/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java index f6d8ad475..46bb76d03 100644 --- a/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java +++ b/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java @@ -43,6 +43,7 @@ import com.datastax.oss.driver.api.core.cql.Row; import com.datastax.oss.driver.api.core.cql.SimpleStatement; import com.datastax.oss.driver.api.core.data.CqlVector; import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; +import com.datastax.oss.driver.api.core.metadata.schema.IndexMetadata; import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; import com.datastax.oss.driver.api.core.type.DataType; import com.datastax.oss.driver.api.core.type.DataTypes; @@ -397,11 +398,16 @@ public class CassandraVectorStore extends AbstractObservationVectorStore impleme private Similarity getIndexSimilarity(TableMetadata metadata) { - return Similarity.valueOf(metadata.getIndex(this.schema.index()) - .get() - .getOptions() - .getOrDefault("similarity_function", "COSINE") - .toUpperCase()); + Optional indexMetadata = metadata.getIndex(this.schema.index()); + + if (indexMetadata.isEmpty()) { + throw new IllegalStateException( + String.format("Index %s does not exist in table %s", this.schema.index(), this.schema.table)); + } + + return Similarity + .valueOf(indexMetadata.get().getOptions().getOrDefault("similarity_function", "COSINE").toUpperCase()); + } private PreparedStatement prepareDeleteStatement() { @@ -554,6 +560,9 @@ public class CassandraVectorStore extends AbstractObservationVectorStore impleme .getTable(this.schema.table) .get(); + Preconditions.checkState(tableMetadata.getIndex(this.schema.index()).isPresent(), "index %s does not exist", + this.schema.index()); + Preconditions.checkState(tableMetadata.getColumn(this.schema.content).isPresent(), "column %s does not exist", this.schema.content); diff --git a/vector-stores/spring-ai-cassandra-store/src/test/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStoreIT.java b/vector-stores/spring-ai-cassandra-store/src/test/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStoreIT.java index 26327e81d..a5993b9c2 100644 --- a/vector-stores/spring-ai-cassandra-store/src/test/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStoreIT.java +++ b/vector-stores/spring-ai-cassandra-store/src/test/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStoreIT.java @@ -522,6 +522,31 @@ class CassandraVectorStoreIT extends BaseVectorStoreTests { }); } + @Test + void throwsExceptionOnInvalidIndexNameWithSchemaValidation() { + this.contextRunner.run(context -> { + // Create valid schema first, then close + try (CassandraVectorStore validStore = createTestStore(context, new SchemaColumn("meta1", DataTypes.TEXT), + new SchemaColumn("meta2", DataTypes.TEXT))) { + // Nothing to do here. This should not fail as the Schema now exists + } + + // Now try with invalid index name but don't reinitialize schema + CassandraVectorStore.Builder invalidBuilder = storeBuilder(context.getBean(CqlSession.class), + context.getBean(EmbeddingModel.class)) + .addMetadataColumns(new SchemaColumn("meta1", DataTypes.TEXT), + new SchemaColumn("meta2", DataTypes.TEXT)) + .indexName("non_existent_index_name") + .initializeSchema(false); + + IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, + invalidBuilder::build); + + assertThat(exception.getMessage()).contains("non_existent_index_name"); + assertThat(exception.getMessage()).contains("does not exist"); + }); + } + @SpringBootConfiguration @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class }) public static class TestApplication {