From 80fd7cd263e5f20bbe9cc70bbc3fd29b91a9cc46 Mon Sep 17 00:00:00 2001 From: Soby Chacko Date: Thu, 12 Dec 2024 17:04:23 -0500 Subject: [PATCH] Weaviate vector store builder refactoring --- .../WeaviateVectorStoreAutoConfiguration.java | 26 +- .../WeaviateVectorStoreProperties.java | 8 +- ...eaviateVectorStoreAutoConfigurationIT.java | 2 +- ...teContainerConnectionDetailsFactoryIT.java | 2 +- .../WeaviateFilterExpressionConverter.java | 2 +- .../{ => weaviate}/WeaviateVectorStore.java | 409 ++++++++++++++++-- ...eaviateFilterExpressionConverterTests.java | 2 +- .../{ => weaviate}/WeaviateImage.java | 2 +- .../{ => weaviate}/WeaviateVectorStoreIT.java | 18 +- .../WeaviateVectorStoreObservationIT.java | 17 +- 10 files changed, 406 insertions(+), 82 deletions(-) rename vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/{ => weaviate}/WeaviateFilterExpressionConverter.java (99%) rename vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/{ => weaviate}/WeaviateVectorStore.java (54%) rename vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/{ => weaviate}/WeaviateFilterExpressionConverterTests.java (99%) rename vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/{ => weaviate}/WeaviateImage.java (94%) rename vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/{ => weaviate}/WeaviateVectorStoreIT.java (94%) rename vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/{ => weaviate}/WeaviateVectorStoreObservationIT.java (94%) diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java index cc0fec8265a..1e710170072 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java @@ -25,9 +25,9 @@ import org.springframework.ai.embedding.BatchingStrategy; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.embedding.TokenCountBatchingStrategy; -import org.springframework.ai.vectorstore.WeaviateVectorStore; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.MetadataField; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore.WeaviateVectorStoreConfig; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore.WeaviateVectorStoreConfig.MetadataField; import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -81,18 +81,20 @@ public WeaviateVectorStore vectorStore(EmbeddingModel embeddingModel, WeaviateCl ObjectProvider customObservationConvention, BatchingStrategy batchingStrategy) { - WeaviateVectorStoreConfig.Builder configBuilder = WeaviateVectorStore.WeaviateVectorStoreConfig.builder() - .withObjectClass(properties.getObjectClass()) - .withFilterableMetadataFields(properties.getFilterField() + return WeaviateVectorStore.builder() + .weaviateClient(weaviateClient) + .embeddingModel(embeddingModel) + .objectClass(properties.getObjectClass()) + .filterMetadataFields(properties.getFilterField() .entrySet() .stream() - .map(e -> new MetadataField(e.getKey(), e.getValue())) + .map(e -> new WeaviateVectorStore.MetadataField(e.getKey(), e.getValue())) .toList()) - .withConsistencyLevel(properties.getConsistencyLevel()); - - return new WeaviateVectorStore(configBuilder.build(), embeddingModel, weaviateClient, - observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP), - customObservationConvention.getIfAvailable(() -> null), batchingStrategy); + .consistencyLevel(WeaviateVectorStore.ConsistentLevel.valueOf(properties.getConsistencyLevel().name())) + .observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)) + .customObservationConvention(customObservationConvention.getIfAvailable(() -> null)) + .batchingStrategy(batchingStrategy) + .build(); } static class PropertiesWeaviateConnectionDetails implements WeaviateConnectionDetails { diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java index a39a0f43e00..08a41eb09db 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java @@ -18,9 +18,9 @@ import java.util.Map; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.ConsistentLevel; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.MetadataField; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore.ConsistentLevel; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore.MetadataField; import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -41,7 +41,7 @@ public class WeaviateVectorStoreProperties { private String objectClass = "SpringAiWeaviate"; - private ConsistentLevel consistencyLevel = WeaviateVectorStoreConfig.ConsistentLevel.ONE; + private ConsistentLevel consistencyLevel = WeaviateVectorStore.ConsistentLevel.ONE; /** * spring.ai.vectorstore.weaviate.filter-field.= diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationIT.java index 02d3b2a3efa..da0e32b35c3 100644 --- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationIT.java +++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationIT.java @@ -32,7 +32,7 @@ import org.springframework.ai.transformers.TransformersEmbeddingModel; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.ai.vectorstore.VectorStore; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.MetadataField; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore.MetadataField; import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/weaviate/WeaviateContainerConnectionDetailsFactoryIT.java b/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/weaviate/WeaviateContainerConnectionDetailsFactoryIT.java index bb81ace4f9a..fe145af9787 100644 --- a/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/weaviate/WeaviateContainerConnectionDetailsFactoryIT.java +++ b/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/weaviate/WeaviateContainerConnectionDetailsFactoryIT.java @@ -32,7 +32,7 @@ import org.springframework.ai.transformers.TransformersEmbeddingModel; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.ai.vectorstore.VectorStore; -import org.springframework.ai.vectorstore.WeaviateVectorStore; +import org.springframework.ai.vectorstore.weaviate.WeaviateVectorStore; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/WeaviateFilterExpressionConverter.java b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverter.java similarity index 99% rename from vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/WeaviateFilterExpressionConverter.java rename to vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverter.java index 2f368d678c0..c3c71119349 100644 --- a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/WeaviateFilterExpressionConverter.java +++ b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.vectorstore.weaviate; import java.util.Date; import java.util.List; diff --git a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/WeaviateVectorStore.java b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java similarity index 54% rename from vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/WeaviateVectorStore.java rename to vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java index cd2110f4ff5..ac1b5f8cea5 100644 --- a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/WeaviateVectorStore.java +++ b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.vectorstore.weaviate; import java.util.ArrayList; import java.util.Arrays; @@ -52,8 +52,8 @@ import org.springframework.ai.embedding.TokenCountBatchingStrategy; import org.springframework.ai.model.EmbeddingUtils; import org.springframework.ai.observation.conventions.VectorStoreProvider; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.ConsistentLevel; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.MetadataField; +import org.springframework.ai.vectorstore.AbstractVectorStoreBuilder; +import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.ai.vectorstore.filter.Filter; import org.springframework.ai.vectorstore.observation.AbstractObservationVectorStore; import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext; @@ -92,8 +92,6 @@ public class WeaviateVectorStore extends AbstractObservationVectorStore { private static final String ADDITIONAL_VECTOR_FIELD_NAME = "vector"; - private final EmbeddingModel embeddingModel; - private final WeaviateClient weaviateClient; private final ConsistentLevel consistencyLevel; @@ -131,11 +129,16 @@ public class WeaviateVectorStore extends AbstractObservationVectorStore { private final ObjectMapper objectMapper = new ObjectMapper(); /** - * Constructs a new WeaviateVectorStore. - * @param vectorStoreConfig The configuration for the store. - * @param embeddingModel The client for embedding operations. - * @param weaviateClient The client for Weaviate operations. + * Constructs a new WeaviateVectorStore with default settings. + * @param vectorStoreConfig The configuration for the store + * @param embeddingModel The client for embedding operations + * @param weaviateClient The client for Weaviate operations + * @deprecated Use {@link #builder()} instead to create instances of + * WeaviateVectorStore. This constructor will be removed in a future release. + * @see #builder() + * @since 1.0.0 */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public WeaviateVectorStore(WeaviateVectorStoreConfig vectorStoreConfig, EmbeddingModel embeddingModel, WeaviateClient weaviateClient) { this(vectorStoreConfig, embeddingModel, weaviateClient, ObservationRegistry.NOOP, null, @@ -143,31 +146,61 @@ public WeaviateVectorStore(WeaviateVectorStoreConfig vectorStoreConfig, Embeddin } /** - * Constructs a new WeaviateVectorStore. - * @param vectorStoreConfig The configuration for the store. - * @param embeddingModel The client for embedding operations. - * @param weaviateClient The client for Weaviate operations. - * @param observationRegistry The registry for observations. - * @param customObservationConvention The custom observation convention. + * Constructs a new WeaviateVectorStore with custom settings. + * @param vectorStoreConfig The configuration for the store + * @param embeddingModel The client for embedding operations + * @param weaviateClient The client for Weaviate operations + * @param observationRegistry The registry for observations + * @param customObservationConvention The custom observation convention + * @param batchingStrategy The strategy for batching operations + * @deprecated Use {@link #builder()} instead to create instances of + * WeaviateVectorStore. This constructor will be removed in a future release. + * @see #builder() + * @since 1.0.0 */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public WeaviateVectorStore(WeaviateVectorStoreConfig vectorStoreConfig, EmbeddingModel embeddingModel, WeaviateClient weaviateClient, ObservationRegistry observationRegistry, VectorStoreObservationConvention customObservationConvention, BatchingStrategy batchingStrategy) { - super(observationRegistry, customObservationConvention); + this(builder().embeddingModel(embeddingModel) + .weaviateClient(weaviateClient) + .observationRegistry(observationRegistry) + .customObservationConvention(customObservationConvention) + .batchingStrategy(batchingStrategy)); + } + + /** + * Protected constructor for creating a WeaviateVectorStore instance using the builder + * pattern. This constructor initializes the vector store with the configured settings + * from the builder and performs necessary validations. + * @param builder the {@link WeaviateBuilder} containing all configuration settings + * @throws IllegalArgumentException if the weaviateClient is null + * @see WeaviateBuilder + * @since 1.0.0 + */ + protected WeaviateVectorStore(WeaviateBuilder builder) { + super(builder); - Assert.notNull(vectorStoreConfig, "WeaviateVectorStoreConfig must not be null"); - Assert.notNull(embeddingModel, "EmbeddingModel must not be null"); + Assert.notNull(builder.weaviateClient, "WeaviateClient must not be null"); - this.embeddingModel = embeddingModel; - this.consistencyLevel = vectorStoreConfig.consistencyLevel; - this.weaviateObjectClass = vectorStoreConfig.weaviateObjectClass; - this.filterMetadataFields = vectorStoreConfig.filterMetadataFields; + this.weaviateClient = builder.weaviateClient; + this.consistencyLevel = builder.consistencyLevel; + this.weaviateObjectClass = builder.weaviateObjectClass; + this.filterMetadataFields = builder.filterMetadataFields; + this.batchingStrategy = builder.batchingStrategy; this.filterExpressionConverter = new WeaviateFilterExpressionConverter( this.filterMetadataFields.stream().map(MetadataField::name).toList()); - this.weaviateClient = weaviateClient; this.weaviateSimilaritySearchFields = buildWeaviateSimilaritySearchFields(); - this.batchingStrategy = batchingStrategy; + } + + /** + * Creates a new WeaviateBuilder instance. This is the recommended way to instantiate + * a WeaviateVectorStore. + * @return a new WeaviateBuilder instance + */ + public static WeaviateBuilder builder() { + return new WeaviateBuilder(); } private Field[] buildWeaviateSimilaritySearchFields() { @@ -402,8 +435,193 @@ public VectorStoreObservationContext.Builder createObservationContextBuilder(Str } /** - * Configuration class for the WeaviateVectorStore. + * Defines the consistency levels for Weaviate operations. + * + * @see Weaviate + * Consistency Strategies + */ + public enum ConsistentLevel { + + /** + * Write must receive an acknowledgement from at least one replica node. This is + * the fastest (most available), but least consistent option. + */ + ONE, + + /** + * Write must receive an acknowledgement from at least QUORUM replica nodes. + * QUORUM is calculated as n / 2 + 1, where n is the number of replicas. + */ + QUORUM, + + /** + * Write must receive an acknowledgement from all replica nodes. This is the most + * consistent, but 'slowest'. + */ + ALL + + } + + /** + * Represents a metadata field configuration for Weaviate vector store. + * + * @param name the name of the metadata field + * @param type the type of the metadata field + */ + public record MetadataField(String name, Type type) { + + /** + * Creates a metadata field of type TEXT. + * @param name the name of the field + * @return a new MetadataField instance of type TEXT + * @throws IllegalArgumentException if name is null or empty + */ + public static MetadataField text(String name) { + Assert.hasText(name, "Field name must not be empty"); + return new MetadataField(name, Type.TEXT); + } + + /** + * Creates a metadata field of type NUMBER. + * @param name the name of the field + * @return a new MetadataField instance of type NUMBER + * @throws IllegalArgumentException if name is null or empty + */ + public static MetadataField number(String name) { + Assert.hasText(name, "Field name must not be empty"); + return new MetadataField(name, Type.NUMBER); + } + + /** + * Creates a metadata field of type BOOLEAN. + * @param name the name of the field + * @return a new MetadataField instance of type BOOLEAN + * @throws IllegalArgumentException if name is null or empty + */ + public static MetadataField bool(String name) { + Assert.hasText(name, "Field name must not be empty"); + return new MetadataField(name, Type.BOOLEAN); + } + + /** + * Defines the supported types for metadata fields. + */ + public enum Type { + + TEXT, NUMBER, BOOLEAN + + } + } + + public static final class WeaviateBuilder extends AbstractVectorStoreBuilder { + + private String weaviateObjectClass = "SpringAiWeaviate"; + + private ConsistentLevel consistencyLevel = ConsistentLevel.ONE; + + private List filterMetadataFields = List.of(); + + private WeaviateClient weaviateClient; + + private BatchingStrategy batchingStrategy = new TokenCountBatchingStrategy(); + + /** + * Configures the Weaviate client. + * @param weaviateClient the client for Weaviate operations + * @return this builder instance + * @throws IllegalArgumentException if weaviateClient is null + */ + public WeaviateBuilder weaviateClient(WeaviateClient weaviateClient) { + Assert.notNull(weaviateClient, "weaviateClient must not be null"); + this.weaviateClient = weaviateClient; + return this; + } + + /** + * Configures the Weaviate object class. + * @param objectClass the object class to use + * @return this builder instance + * @throws IllegalArgumentException if objectClass is null or empty + */ + public WeaviateBuilder objectClass(String objectClass) { + Assert.hasText(objectClass, "objectClass must not be empty"); + this.weaviateObjectClass = objectClass; + return this; + } + + /** + * Configures the consistency level for Weaviate operations. + * @param consistencyLevel the consistency level to use + * @return this builder instance + * @throws IllegalArgumentException if consistencyLevel is null + */ + public WeaviateBuilder consistencyLevel(ConsistentLevel consistencyLevel) { + Assert.notNull(consistencyLevel, "consistencyLevel must not be null"); + this.consistencyLevel = consistencyLevel; + return this; + } + + /** + * Configures the filterable metadata fields. + * @param filterMetadataFields list of metadata fields that can be used in filters + * @return this builder instance + * @throws IllegalArgumentException if filterMetadataFields is null + */ + public WeaviateBuilder filterMetadataFields(List filterMetadataFields) { + Assert.notNull(filterMetadataFields, "filterMetadataFields must not be null"); + this.filterMetadataFields = filterMetadataFields; + return this; + } + + /** + * Configures the batching strategy. + * @param batchingStrategy the strategy for batching operations + * @return this builder instance + * @throws IllegalArgumentException if batchingStrategy is null + */ + public WeaviateBuilder batchingStrategy(BatchingStrategy batchingStrategy) { + Assert.notNull(batchingStrategy, "batchingStrategy must not be null"); + this.batchingStrategy = batchingStrategy; + return this; + } + + /** + * Builds and returns a new WeaviateVectorStore instance with the configured + * settings. + * @return a new WeaviateVectorStore instance + * @throws IllegalStateException if the builder configuration is invalid + */ + @Override + public WeaviateVectorStore build() { + validate(); + return new WeaviateVectorStore(this); + } + + } + + /** + * Configuration class for WeaviateVectorStore. + * + * @deprecated Use {@link WeaviateVectorStore#builder()} instead to configure and + * create instances of WeaviateVectorStore. This class will be removed in a future + * release. Example migration:
{@code
+	 * // Old approach:
+	 * WeaviateVectorStoreConfig config = WeaviateVectorStoreConfig.builder()
+	 *     .withObjectClass("CustomClass")
+	 *     .withConsistencyLevel(ConsistentLevel.QUORUM)
+	 *     .build();
+	 *
+	 * // New approach:
+	 * WeaviateVectorStore store = WeaviateVectorStore.builder()
+	 *     .objectClass("CustomClass")
+	 *     .consistencyLevel(ConsistentLevel.QUORUM)
+	 *     .build();
+	 * }
+ * @see WeaviateVectorStore#builder() + * @since 1.0.0 */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public static final class WeaviateVectorStoreConfig { private final String weaviateObjectClass; @@ -421,8 +639,10 @@ public static final class WeaviateVectorStoreConfig { /** * Constructor using the builder. - * @param builder The configuration builder. + * @param builder The configuration builder + * @deprecated Use {@link WeaviateVectorStore#builder()} instead */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public WeaviateVectorStoreConfig(Builder builder) { this.weaviateObjectClass = builder.objectClass; this.consistencyLevel = builder.consistencyLevel; @@ -432,22 +652,43 @@ public WeaviateVectorStoreConfig(Builder builder) { /** * Start building a new configuration. - * @return The entry point for creating a new configuration. + * @return The entry point for creating a new configuration + * @deprecated Use {@link WeaviateVectorStore#builder()} instead to configure and + * create instances of WeaviateVectorStore */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public static Builder builder() { return new Builder(); } /** - * {@return the default config} + * Returns the default configuration. + * @return the default configuration + * @deprecated Use {@link WeaviateVectorStore#builder()} instead to configure and + * create instances of WeaviateVectorStore with default settings */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public static WeaviateVectorStoreConfig defaultConfig() { return builder().build(); } /** - * https://weaviate.io/developers/weaviate/concepts/replication-architecture/consistency#tunable-consistency-strategies + * Defines the consistency levels for Weaviate operations. + * + * @see Weaviate + * Consistency Strategies + * @deprecated Use {@link WeaviateVectorStore.ConsistentLevel} instead. This enum + * will be removed in a future release. Example migration:
{@code
+		 * // Old approach:
+		 * WeaviateVectorStoreConfig.ConsistentLevel level = WeaviateVectorStoreConfig.ConsistentLevel.QUORUM;
+		 *
+		 * // New approach:
+		 * WeaviateVectorStore.ConsistentLevel level = WeaviateVectorStore.ConsistentLevel.QUORUM;
+		 * }
+ * @since 1.0.0 */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public enum ConsistentLevel { /** @@ -470,33 +711,91 @@ public enum ConsistentLevel { } + /** + * Represents a metadata field configuration for Weaviate vector store. + * + * @param name the name of the metadata field + * @param type the type of the metadata field + * @deprecated Use {@link WeaviateVectorStore.MetadataField} instead. This record + * will be removed in a future release. Example migration:
{@code
+		 * // Old approach:
+		 * WeaviateVectorStoreConfig.MetadataField field = WeaviateVectorStoreConfig.MetadataField.text("field");
+		 *
+		 * // New approach:
+		 * WeaviateVectorStore.MetadataField field = WeaviateVectorStore.MetadataField.text("field");
+		 * }
+ * @since 1.0.0 + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public record MetadataField(String name, Type type) { + /** + * Creates a metadata field of type TEXT. + * @param name the name of the field + * @return a new MetadataField instance of type TEXT + * @throws IllegalArgumentException if name is null or empty + * @deprecated Use {@link WeaviateVectorStore.MetadataField#text(String)} + * instead + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public static MetadataField text(String name) { return new MetadataField(name, Type.TEXT); } + /** + * Creates a metadata field of type NUMBER. + * @param name the name of the field + * @return a new MetadataField instance of type NUMBER + * @throws IllegalArgumentException if name is null or empty + * @deprecated Use {@link WeaviateVectorStore.MetadataField#number(String)} + * instead + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public static MetadataField number(String name) { return new MetadataField(name, Type.NUMBER); } + /** + * Creates a metadata field of type BOOLEAN. + * @param name the name of the field + * @return a new MetadataField instance of type BOOLEAN + * @throws IllegalArgumentException if name is null or empty + * @deprecated Use {@link WeaviateVectorStore.MetadataField#bool(String)} + * instead + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public static MetadataField bool(String name) { return new MetadataField(name, Type.BOOLEAN); } + /** + * Defines the supported types for metadata fields. + * + * @deprecated Use {@link WeaviateVectorStore.MetadataField.Type} instead. + * This enum will be removed in a future release. + * @since 1.0.0 + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public enum Type { TEXT, NUMBER, BOOLEAN } - } + /** + * Builder for WeaviateVectorStoreConfig. + * + * @deprecated Use {@link WeaviateVectorStore#builder()} instead to configure and + * create instances of WeaviateVectorStore + * @since 1.0.0 + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public static final class Builder { private String objectClass = "SpringAiWeaviate"; - private ConsistentLevel consistencyLevel = WeaviateVectorStoreConfig.ConsistentLevel.ONE; + private ConsistentLevel consistencyLevel = ConsistentLevel.ONE; private List filterMetadataFields = List.of(); @@ -506,10 +805,15 @@ private Builder() { } /** - * Weaviate known, filterable metadata fields. - * @param filterMetadataFields known metadata fields to use. - * @return this builder. + * Configures the filterable metadata fields. + * @param filterMetadataFields known metadata fields to use + * @return this builder + * @throws IllegalArgumentException if filterMetadataFields is null + * @deprecated Use + * {@link WeaviateVectorStore.WeaviateBuilder#filterMetadataFields(List)} + * instead */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withFilterableMetadataFields(List filterMetadataFields) { Assert.notNull(filterMetadataFields, "The filterMetadataFields can not be null."); this.filterMetadataFields = filterMetadataFields; @@ -517,10 +821,14 @@ public Builder withFilterableMetadataFields(List filterMetadataFi } /** - * Weaviate config headers. - * @param headers config headers to use. - * @return this builder. + * Configures the Weaviate config headers. + * @param headers config headers to use + * @return this builder + * @throws IllegalArgumentException if headers is null + * @deprecated Use the new builder API in + * {@link WeaviateVectorStore#builder()} */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withHeaders(Map headers) { Assert.notNull(headers, "The headers can not be null."); this.headers = headers; @@ -528,10 +836,14 @@ public Builder withHeaders(Map headers) { } /** - * Weaviate objectClass. - * @param objectClass objectClass to use. - * @return this builder. + * Configures the Weaviate objectClass. + * @param objectClass objectClass to use + * @return this builder + * @throws IllegalArgumentException if objectClass is empty or null + * @deprecated Use + * {@link WeaviateVectorStore.WeaviateBuilder#objectClass(String)} instead */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withObjectClass(String objectClass) { Assert.hasText(objectClass, "The objectClass can not be empty."); this.objectClass = objectClass; @@ -539,10 +851,15 @@ public Builder withObjectClass(String objectClass) { } /** - * Weaviate consistencyLevel. - * @param consistencyLevel consistencyLevel to use. - * @return this builder. + * Configures the Weaviate consistencyLevel. + * @param consistencyLevel consistencyLevel to use + * @return this builder + * @throws IllegalArgumentException if consistencyLevel is null + * @deprecated Use + * {@link WeaviateVectorStore.WeaviateBuilder#consistencyLevel(WeaviateVectorStore.ConsistentLevel)} + * instead */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withConsistencyLevel(ConsistentLevel consistencyLevel) { Assert.notNull(consistencyLevel, "The consistencyLevel can not be null."); this.consistencyLevel = consistencyLevel; @@ -550,8 +867,12 @@ public Builder withConsistencyLevel(ConsistentLevel consistencyLevel) { } /** - * {@return the immutable configuration} + * Builds and returns the immutable configuration. + * @return the immutable configuration + * @deprecated Use {@link WeaviateVectorStore#builder()} instead to configure + * and create instances of WeaviateVectorStore */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public WeaviateVectorStoreConfig build() { return new WeaviateVectorStoreConfig(this); } diff --git a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateFilterExpressionConverterTests.java b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverterTests.java similarity index 99% rename from vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateFilterExpressionConverterTests.java rename to vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverterTests.java index f06f2ad5de1..8a56b8d9377 100644 --- a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateFilterExpressionConverterTests.java +++ b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.vectorstore.weaviate; import java.util.List; diff --git a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateImage.java b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateImage.java similarity index 94% rename from vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateImage.java rename to vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateImage.java index 8d13d9b302b..99a52997401 100644 --- a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateImage.java +++ b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateImage.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.vectorstore.weaviate; import org.testcontainers.utility.DockerImageName; diff --git a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateVectorStoreIT.java b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreIT.java similarity index 94% rename from vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateVectorStoreIT.java rename to vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreIT.java index 7239b319b61..b675b5f9688 100644 --- a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateVectorStoreIT.java +++ b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreIT.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.vectorstore.weaviate; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -35,8 +35,8 @@ import org.springframework.ai.document.Document; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.transformers.TransformersEmbeddingModel; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.MetadataField; +import org.springframework.ai.vectorstore.SearchRequest; +import org.springframework.ai.vectorstore.VectorStore; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -252,13 +252,13 @@ public VectorStore vectorStore(EmbeddingModel embeddingModel) { WeaviateClient weaviateClient = new WeaviateClient( new Config("http", weaviateContainer.getHttpHostAddress())); - WeaviateVectorStoreConfig config = WeaviateVectorStore.WeaviateVectorStoreConfig.builder() - .withFilterableMetadataFields(List.of(MetadataField.text("country"), MetadataField.number("year"))) - .withConsistencyLevel(WeaviateVectorStoreConfig.ConsistentLevel.ONE) + return WeaviateVectorStore.builder() + .weaviateClient(weaviateClient) + .embeddingModel(embeddingModel) + .filterMetadataFields(List.of(WeaviateVectorStore.MetadataField.text("country"), + WeaviateVectorStore.MetadataField.number("year"))) + .consistencyLevel(WeaviateVectorStore.ConsistentLevel.ONE) .build(); - - return new WeaviateVectorStore(config, embeddingModel, weaviateClient); - } @Bean diff --git a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateVectorStoreObservationIT.java b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreObservationIT.java similarity index 94% rename from vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateVectorStoreObservationIT.java rename to vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreObservationIT.java index 17b54c1881c..b3b8ea8f7c3 100644 --- a/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/WeaviateVectorStoreObservationIT.java +++ b/vector-stores/spring-ai-weaviate-store/src/test/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreObservationIT.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.vectorstore.weaviate; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -37,7 +37,8 @@ import org.springframework.ai.observation.conventions.SpringAiKind; import org.springframework.ai.observation.conventions.VectorStoreProvider; import org.springframework.ai.transformers.TransformersEmbeddingModel; -import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig; +import org.springframework.ai.vectorstore.SearchRequest; +import org.springframework.ai.vectorstore.VectorStore; import org.springframework.ai.vectorstore.observation.DefaultVectorStoreObservationConvention; import org.springframework.ai.vectorstore.observation.VectorStoreObservationDocumentation.HighCardinalityKeyNames; import org.springframework.ai.vectorstore.observation.VectorStoreObservationDocumentation.LowCardinalityKeyNames; @@ -165,13 +166,13 @@ public WeaviateVectorStore vectorStore(EmbeddingModel embeddingModel, Observatio WeaviateClient weaviateClient = new WeaviateClient( new io.weaviate.client.Config("http", weaviateContainer.getHttpHostAddress())); - WeaviateVectorStoreConfig config = WeaviateVectorStore.WeaviateVectorStoreConfig.builder() - .withConsistencyLevel(WeaviateVectorStoreConfig.ConsistentLevel.ONE) + return WeaviateVectorStore.builder() + .weaviateClient(weaviateClient) + .embeddingModel(embeddingModel) + .consistencyLevel(WeaviateVectorStore.ConsistentLevel.ONE) + .observationRegistry(observationRegistry) + .batchingStrategy(new TokenCountBatchingStrategy()) .build(); - - return new WeaviateVectorStore(config, embeddingModel, weaviateClient, observationRegistry, null, - new TokenCountBatchingStrategy()); - } @Bean