diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/mongo/MongoDBAtlasVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/mongo/MongoDBAtlasVectorStoreAutoConfiguration.java index aaadea3bb2b..7b8e0cabae4 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/mongo/MongoDBAtlasVectorStoreAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/mongo/MongoDBAtlasVectorStoreAutoConfiguration.java @@ -17,13 +17,14 @@ package org.springframework.ai.autoconfigure.vectorstore.mongo; import java.util.Arrays; +import java.util.List; import io.micrometer.observation.ObservationRegistry; import org.springframework.ai.embedding.BatchingStrategy; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.embedding.TokenCountBatchingStrategy; -import org.springframework.ai.vectorstore.MongoDBAtlasVectorStore; +import org.springframework.ai.mongodb.atlas.vectorstore.MongoDBAtlasVectorStore; import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -34,6 +35,7 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.convert.MongoCustomConversions; +import org.springframework.util.CollectionUtils; import org.springframework.util.MimeType; import org.springframework.util.StringUtils; @@ -64,25 +66,35 @@ MongoDBAtlasVectorStore vectorStore(MongoTemplate mongoTemplate, EmbeddingModel ObjectProvider customObservationConvention, BatchingStrategy batchingStrategy) { - var builder = MongoDBAtlasVectorStore.MongoDBVectorStoreConfig.builder(); - - if (StringUtils.hasText(properties.getCollectionName())) { - builder.withCollectionName(properties.getCollectionName()); + MongoDBAtlasVectorStore.MongoDBBuilder builder = MongoDBAtlasVectorStore.builder() + .mongoTemplate(mongoTemplate) + .embeddingModel(embeddingModel) + .initializeSchema(properties.isInitializeSchema()) + .observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)) + .customObservationConvention(customObservationConvention.getIfAvailable(() -> null)) + .batchingStrategy(batchingStrategy); + + String collectionName = properties.getCollectionName(); + if (StringUtils.hasText(collectionName)) { + builder.collectionName(collectionName); } - if (StringUtils.hasText(properties.getPathName())) { - builder.withPathName(properties.getPathName()); + + String pathName = properties.getPathName(); + if (StringUtils.hasText(pathName)) { + builder.pathName(pathName); } - if (StringUtils.hasText(properties.getIndexName())) { - builder.withVectorIndexName(properties.getIndexName()); + + String indexName = properties.getIndexName(); + if (StringUtils.hasText(indexName)) { + builder.vectorIndexName(indexName); } - if (!properties.getMetadataFieldsToFilter().isEmpty()) { - builder.withMetadataFieldsToFilter(properties.getMetadataFieldsToFilter()); + + List metadataFields = properties.getMetadataFieldsToFilter(); + if (!CollectionUtils.isEmpty(metadataFields)) { + builder.metadataFieldsToFilter(metadataFields); } - MongoDBAtlasVectorStore.MongoDBVectorStoreConfig config = builder.build(); - return new MongoDBAtlasVectorStore(mongoTemplate, embeddingModel, config, properties.isInitializeSchema(), - observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP), - customObservationConvention.getIfAvailable(() -> null), batchingStrategy); + return builder.build(); } @Bean diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterExpressionConverter.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasFilterExpressionConverter.java similarity index 98% rename from vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterExpressionConverter.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasFilterExpressionConverter.java index c72f51c4f41..01d819c8587 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterExpressionConverter.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasFilterExpressionConverter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import org.springframework.ai.vectorstore.filter.Filter; import org.springframework.ai.vectorstore.filter.converter.AbstractFilterExpressionConverter; diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasVectorStore.java similarity index 59% rename from vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasVectorStore.java index 96fec62234b..4cdb2cd6473 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasVectorStore.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import java.util.ArrayList; import java.util.Collections; @@ -33,6 +33,9 @@ import org.springframework.ai.embedding.TokenCountBatchingStrategy; import org.springframework.ai.model.EmbeddingUtils; import org.springframework.ai.observation.conventions.VectorStoreProvider; +import org.springframework.ai.vectorstore.AbstractVectorStoreBuilder; +import org.springframework.ai.vectorstore.SearchRequest; +import org.springframework.ai.vectorstore.VectorStore; import org.springframework.ai.vectorstore.observation.AbstractObservationVectorStore; import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext; import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention; @@ -78,39 +81,67 @@ public class MongoDBAtlasVectorStore extends AbstractObservationVectorStore impl private final MongoTemplate mongoTemplate; - private final EmbeddingModel embeddingModel; + private final String collectionName; - private final MongoDBVectorStoreConfig config; + private final String vectorIndexName; - private final MongoDBAtlasFilterExpressionConverter filterExpressionConverter = new MongoDBAtlasFilterExpressionConverter(); + private final String pathName; + + private final List metadataFieldsToFilter; + + private final int numCandidates; + + private final MongoDBAtlasFilterExpressionConverter filterExpressionConverter; private final boolean initializeSchema; private final BatchingStrategy batchingStrategy; + @Deprecated(since = "1.0.0-M5", forRemoval = true) public MongoDBAtlasVectorStore(MongoTemplate mongoTemplate, EmbeddingModel embeddingModel, boolean initializeSchema) { this(mongoTemplate, embeddingModel, MongoDBVectorStoreConfig.defaultConfig(), initializeSchema); } + @Deprecated(since = "1.0.0-M5", forRemoval = true) public MongoDBAtlasVectorStore(MongoTemplate mongoTemplate, EmbeddingModel embeddingModel, MongoDBVectorStoreConfig config, boolean initializeSchema) { this(mongoTemplate, embeddingModel, config, initializeSchema, ObservationRegistry.NOOP, null, new TokenCountBatchingStrategy()); } + @Deprecated(since = "1.0.0-M5", forRemoval = true) public MongoDBAtlasVectorStore(MongoTemplate mongoTemplate, EmbeddingModel embeddingModel, MongoDBVectorStoreConfig config, boolean initializeSchema, ObservationRegistry observationRegistry, VectorStoreObservationConvention customObservationConvention, BatchingStrategy batchingStrategy) { - super(observationRegistry, customObservationConvention); + this(builder().mongoTemplate(mongoTemplate) + .embeddingModel(embeddingModel) + .collectionName(config.collectionName) + .vectorIndexName(config.vectorIndexName) + .pathName(config.pathName) + .numCandidates(config.numCandidates) + .metadataFieldsToFilter(config.metadataFieldsToFilter) + .initializeSchema(initializeSchema) + .observationRegistry(observationRegistry) + .customObservationConvention(customObservationConvention) + .batchingStrategy(batchingStrategy)); + } + + protected MongoDBAtlasVectorStore(MongoDBBuilder builder) { + super(builder); - this.mongoTemplate = mongoTemplate; - this.embeddingModel = embeddingModel; - this.config = config; + Assert.notNull(builder.mongoTemplate, "MongoTemplate must not be null"); - this.initializeSchema = initializeSchema; - this.batchingStrategy = batchingStrategy; + this.mongoTemplate = builder.mongoTemplate; + this.collectionName = builder.collectionName; + this.vectorIndexName = builder.vectorIndexName; + this.pathName = builder.pathName; + this.numCandidates = builder.numCandidates; + this.metadataFieldsToFilter = builder.metadataFieldsToFilter; + this.filterExpressionConverter = builder.filterExpressionConverter; + this.initializeSchema = builder.initializeSchema; + this.batchingStrategy = builder.batchingStrategy; } @Override @@ -120,8 +151,8 @@ public void afterPropertiesSet() throws Exception { } // Create the collection if it does not exist - if (!this.mongoTemplate.collectionExists(this.config.collectionName)) { - this.mongoTemplate.createCollection(this.config.collectionName); + if (!this.mongoTemplate.collectionExists(this.collectionName)) { + this.mongoTemplate.createCollection(this.collectionName); } // Create search index createSearchIndex(); @@ -151,17 +182,17 @@ private org.bson.Document createSearchIndexDefinition() { List vectorFields = new ArrayList<>(); vectorFields.add(new org.bson.Document().append("type", "vector") - .append("path", this.config.pathName) + .append("path", this.pathName) .append("numDimensions", this.embeddingModel.dimensions()) .append("similarity", "cosine")); - vectorFields.addAll(this.config.metadataFieldsToFilter.stream() + vectorFields.addAll(this.metadataFieldsToFilter.stream() .map(fieldName -> new org.bson.Document().append("type", "filter").append("path", "metadata." + fieldName)) .toList()); - return new org.bson.Document().append("createSearchIndexes", this.config.collectionName) + return new org.bson.Document().append("createSearchIndexes", this.collectionName) .append("indexes", - List.of(new org.bson.Document().append("name", this.config.vectorIndexName) + List.of(new org.bson.Document().append("name", this.vectorIndexName) .append("type", "vectorSearch") .append("definition", new org.bson.Document("fields", vectorFields)))); } @@ -195,7 +226,7 @@ public void doAdd(List documents) { for (Document document : documents) { MongoDBDocument mdbDocument = new MongoDBDocument(document.getId(), document.getContent(), document.getMetadata(), embeddings.get(documents.indexOf(document))); - this.mongoTemplate.save(mdbDocument, this.config.collectionName); + this.mongoTemplate.save(mdbDocument, this.collectionName); } } @@ -203,7 +234,7 @@ public void doAdd(List documents) { public Optional doDelete(List idList) { Query query = new Query(org.springframework.data.mongodb.core.query.Criteria.where(ID_FIELD_NAME).in(idList)); - var deleteRes = this.mongoTemplate.remove(query, this.config.collectionName); + var deleteRes = this.mongoTemplate.remove(query, this.collectionName); long deleteCount = deleteRes.getDeletedCount(); return Optional.of(deleteCount == idList.size()); @@ -221,8 +252,8 @@ public List doSimilaritySearch(SearchRequest request) { ? this.filterExpressionConverter.convertExpression(request.getFilterExpression()) : ""; float[] queryEmbedding = this.embeddingModel.embed(request.getQuery()); - var vectorSearch = new VectorSearchAggregation(EmbeddingUtils.toList(queryEmbedding), this.config.pathName, - this.config.numCandidates, this.config.vectorIndexName, request.getTopK(), nativeFilterExpressions); + var vectorSearch = new VectorSearchAggregation(EmbeddingUtils.toList(queryEmbedding), this.pathName, + this.numCandidates, this.vectorIndexName, request.getTopK(), nativeFilterExpressions); Aggregation aggregation = Aggregation.newAggregation(vectorSearch, Aggregation.addFields() @@ -231,7 +262,7 @@ public List doSimilaritySearch(SearchRequest request) { .build(), Aggregation.match(new Criteria(SCORE_FIELD_NAME).gte(request.getSimilarityThreshold()))); - return this.mongoTemplate.aggregate(aggregation, this.config.collectionName, org.bson.Document.class) + return this.mongoTemplate.aggregate(aggregation, this.collectionName, org.bson.Document.class) .getMappedResults() .stream() .map(d -> mapMongoDocument(d, queryEmbedding)) @@ -242,11 +273,157 @@ public List doSimilaritySearch(SearchRequest request) { public VectorStoreObservationContext.Builder createObservationContextBuilder(String operationName) { return VectorStoreObservationContext.builder(VectorStoreProvider.MONGODB.value(), operationName) - .withCollectionName(this.config.collectionName) + .withCollectionName(this.collectionName) .withDimensions(this.embeddingModel.dimensions()) - .withFieldName(this.config.pathName); + .withFieldName(this.pathName); + } + + /** + * Creates a new builder instance for MongoDBAtlasVectorStore. + * @return a new MongoDBBuilder instance + */ + public static MongoDBBuilder builder() { + return new MongoDBBuilder(); + } + + public static class MongoDBBuilder extends AbstractVectorStoreBuilder { + + private MongoTemplate mongoTemplate; + + private String collectionName = DEFAULT_VECTOR_COLLECTION_NAME; + + private String vectorIndexName = DEFAULT_VECTOR_INDEX_NAME; + + private String pathName = DEFAULT_PATH_NAME; + + private int numCandidates = DEFAULT_NUM_CANDIDATES; + + private List metadataFieldsToFilter = Collections.emptyList(); + + private boolean initializeSchema = false; + + private BatchingStrategy batchingStrategy = new TokenCountBatchingStrategy(); + + private MongoDBAtlasFilterExpressionConverter filterExpressionConverter = new MongoDBAtlasFilterExpressionConverter(); + + /** + * @throws IllegalArgumentException if mongoTemplate is null + */ + public MongoDBBuilder mongoTemplate(MongoTemplate mongoTemplate) { + Assert.notNull(mongoTemplate, "MongoTemplate must not be null"); + this.mongoTemplate = mongoTemplate; + return this; + } + + /** + * Configures the collection name. This must match the name of the collection for + * the Vector Search Index in Atlas. + * @param collectionName the name of the collection + * @return the builder instance + * @throws IllegalArgumentException if collectionName is null or empty + */ + public MongoDBBuilder collectionName(String collectionName) { + Assert.hasText(collectionName, "Collection Name must not be null or empty"); + this.collectionName = collectionName; + return this; + } + + /** + * Configures the vector index name. This must match the name of the Vector Search + * Index Name in Atlas. + * @param vectorIndexName the name of the vector index + * @return the builder instance + * @throws IllegalArgumentException if vectorIndexName is null or empty + */ + public MongoDBBuilder vectorIndexName(String vectorIndexName) { + Assert.hasText(vectorIndexName, "Vector Index Name must not be null or empty"); + this.vectorIndexName = vectorIndexName; + return this; + } + + /** + * Configures the path name. This must match the name of the field indexed for the + * Vector Search Index in Atlas. + * @param pathName the name of the path + * @return the builder instance + * @throws IllegalArgumentException if pathName is null or empty + */ + public MongoDBBuilder pathName(String pathName) { + Assert.hasText(pathName, "Path Name must not be null or empty"); + this.pathName = pathName; + return this; + } + + /** + * Sets the number of candidates for vector search. + * @param numCandidates the number of candidates + * @return the builder instance + */ + public MongoDBBuilder numCandidates(int numCandidates) { + this.numCandidates = numCandidates; + return this; + } + + /** + * Sets the metadata fields to filter in vector search. + * @param metadataFieldsToFilter list of metadata field names + * @return the builder instance + * @throws IllegalArgumentException if metadataFieldsToFilter is null or empty + */ + public MongoDBBuilder metadataFieldsToFilter(List metadataFieldsToFilter) { + Assert.notEmpty(metadataFieldsToFilter, "Fields list must not be empty"); + this.metadataFieldsToFilter = metadataFieldsToFilter; + return this; + } + + /** + * Sets whether to initialize the schema. + * @param initializeSchema true to initialize schema, false otherwise + * @return the builder instance + */ + public MongoDBBuilder initializeSchema(boolean initializeSchema) { + this.initializeSchema = initializeSchema; + return this; + } + + /** + * Sets the batching strategy for vector operations. + * @param batchingStrategy the batching strategy to use + * @return the builder instance + * @throws IllegalArgumentException if batchingStrategy is null + */ + public MongoDBBuilder batchingStrategy(BatchingStrategy batchingStrategy) { + Assert.notNull(batchingStrategy, "batchingStrategy must not be null"); + this.batchingStrategy = batchingStrategy; + return this; + } + + /** + * Sets the filter expression converter. + * @param converter the filter expression converter to use + * @return the builder instance + * @throws IllegalArgumentException if converter is null + */ + public MongoDBBuilder filterExpressionConverter(MongoDBAtlasFilterExpressionConverter converter) { + Assert.notNull(converter, "filterExpressionConverter must not be null"); + this.filterExpressionConverter = converter; + return this; + } + + /** + * Builds the MongoDBAtlasVectorStore instance. + * @return a new MongoDBAtlasVectorStore instance + * @throws IllegalStateException if the builder is in an invalid state + */ + @Override + public MongoDBAtlasVectorStore build() { + validate(); + return new MongoDBAtlasVectorStore(this); + } + } + @Deprecated(since = "1.0.0-M5", forRemoval = true) public static final class MongoDBVectorStoreConfig { private final String collectionName; @@ -267,14 +444,17 @@ private MongoDBVectorStoreConfig(Builder builder) { this.metadataFieldsToFilter = builder.metadataFieldsToFilter; } + @Deprecated(since = "1.0.0-M5", forRemoval = true) public static Builder builder() { return new Builder(); } + @Deprecated(since = "1.0.0-M5", forRemoval = true) public static MongoDBVectorStoreConfig defaultConfig() { return builder().build(); } + @Deprecated(since = "1.0.0-M5", forRemoval = true) public static final class Builder { private String collectionName = DEFAULT_VECTOR_COLLECTION_NAME; @@ -297,7 +477,6 @@ private Builder() { * @return this builder */ public Builder withCollectionName(String collectionName) { - Assert.notNull(collectionName, "Collection Name must not be null"); Assert.notNull(collectionName, "Collection Name must not be empty"); this.collectionName = collectionName; return this; @@ -310,7 +489,6 @@ public Builder withCollectionName(String collectionName) { * @return this builder */ public Builder withVectorIndexName(String vectorIndexName) { - Assert.notNull(vectorIndexName, "Vector Index Name must not be null"); Assert.notNull(vectorIndexName, "Vector Index Name must not be empty"); this.vectorIndexName = vectorIndexName; return this; @@ -323,7 +501,6 @@ public Builder withVectorIndexName(String vectorIndexName) { * @return this builder */ public Builder withPathName(String pathName) { - Assert.notNull(pathName, "Path Name must not be null"); Assert.notNull(pathName, "Path Name must not be empty"); this.pathName = pathName; return this; diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/VectorSearchAggregation.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/VectorSearchAggregation.java similarity index 96% rename from vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/VectorSearchAggregation.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/VectorSearchAggregation.java index b741193dd09..1ade068beca 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/VectorSearchAggregation.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/mongodb/atlas/vectorstore/VectorSearchAggregation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import java.util.List; diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterConverterTest.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasFilterConverterTest.java similarity index 98% rename from vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterConverterTest.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasFilterConverterTest.java index a8df6929e94..d7e6d13035d 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterConverterTest.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasFilterConverterTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import java.util.List; diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStoreIT.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasVectorStoreIT.java similarity index 96% rename from vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStoreIT.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasVectorStoreIT.java index 4eced845ed8..6cce96fca1c 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStoreIT.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDBAtlasVectorStoreIT.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -30,6 +30,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import org.springframework.ai.document.DocumentMetadata; +import org.springframework.ai.vectorstore.SearchRequest; +import org.springframework.ai.vectorstore.VectorStore; import org.springframework.core.io.DefaultResourceLoader; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -257,11 +259,12 @@ public static class TestApplication { @Bean public VectorStore vectorStore(MongoTemplate mongoTemplate, EmbeddingModel embeddingModel) { - return new MongoDBAtlasVectorStore(mongoTemplate, embeddingModel, - MongoDBAtlasVectorStore.MongoDBVectorStoreConfig.builder() - .withMetadataFieldsToFilter(List.of("country", "year")) - .build(), - true); + return MongoDBAtlasVectorStore.builder() + .mongoTemplate(mongoTemplate) + .embeddingModel(embeddingModel) + .metadataFieldsToFilter(List.of("country", "year")) + .initializeSchema(true) + .build(); } @Bean diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDbImage.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDbImage.java similarity index 93% rename from vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDbImage.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDbImage.java index 9a07309bcc8..e6a97602473 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDbImage.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDbImage.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import org.testcontainers.utility.DockerImageName; diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDbVectorStoreObservationIT.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDbVectorStoreObservationIT.java similarity index 94% rename from vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDbVectorStoreObservationIT.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDbVectorStoreObservationIT.java index b8ddad7b43d..287242798e6 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDbVectorStoreObservationIT.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/MongoDbVectorStoreObservationIT.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -40,6 +40,8 @@ import org.springframework.ai.observation.conventions.VectorStoreProvider; import org.springframework.ai.openai.OpenAiEmbeddingModel; import org.springframework.ai.openai.api.OpenAiApi; +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; @@ -185,11 +187,15 @@ public TestObservationRegistry observationRegistry() { @Bean public VectorStore vectorStore(MongoTemplate mongoTemplate, EmbeddingModel embeddingModel, ObservationRegistry observationRegistry) { - return new MongoDBAtlasVectorStore(mongoTemplate, embeddingModel, - MongoDBAtlasVectorStore.MongoDBVectorStoreConfig.builder() - .withMetadataFieldsToFilter(List.of("country", "year")) - .build(), - true, observationRegistry, null, new TokenCountBatchingStrategy()); + return MongoDBAtlasVectorStore.builder() + .mongoTemplate(mongoTemplate) + .embeddingModel(embeddingModel) + .metadataFieldsToFilter(List.of("country", "year")) + .initializeSchema(true) + .observationRegistry(observationRegistry) + .customObservationConvention(null) + .batchingStrategy(new TokenCountBatchingStrategy()) + .build(); } @Bean diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/VectorSearchAggregationTest.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/VectorSearchAggregationTest.java similarity index 97% rename from vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/VectorSearchAggregationTest.java rename to vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/VectorSearchAggregationTest.java index 3e6cce348bb..c34c6446416 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/VectorSearchAggregationTest.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/mongodb/atlas/vectorstore/VectorSearchAggregationTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.ai.vectorstore; +package org.springframework.ai.mongodb.atlas.vectorstore; import java.util.List;