MongoDB Atlas

本节将指导您如何设置 MongoDB Atlas 作为向量存储,以便与 Spring AI 一起使用。

什么是 MongoDB Atlas?

MongoDB Atlas 是 MongoDB 提供的完全托管的云数据库,可在 AWS、Azure 和 GCP 上使用。Atlas 支持对您的 MongoDB 文档数据进行原生向量搜索和全文搜索。

MongoDB Atlas 向量搜索 允许您将嵌入存储在 MongoDB 文档中,创建向量搜索索引,并使用近似最近邻算法 (Hierarchical Navigable Small Worlds) 执行 KNN 搜索。您可以在 MongoDB 聚合阶段中使用$vectorSearch 聚合运算符来对您的向量嵌入执行搜索。

前提条件

  • 运行 MongoDB 6.0.11、7.0.2 或更高版本的 Atlas 集群。要开始使用 MongoDB Atlas,您可以按照此处的说明进行操作。确保您的 IP 地址已包含在 Atlas 项目的 访问列表 中。

  • 一个EmbeddingModel 实例来计算文档嵌入。有多种选择可用。有关更多信息,请参阅EmbeddingModel 部分。

  • 一个用于设置和运行 Java 应用程序的环境。

自动配置

Spring AI 为 MongoDB Atlas 向量存储提供 Spring Boot 自动配置。要启用它,请将以下依赖项添加到项目的 Maven pom.xml 文件

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mongodb-atlas-store-spring-boot-starter</artifactId>
</dependency>

或您的 Gradle build.gradle 构建文件中。

dependencies {
    implementation 'org.springframework.ai:spring-ai-mongodb-atlas-store-spring-boot-starter'
}

向量存储实现可以为您初始化必要的模式,但您必须选择加入,方法是在相应的构造函数中指定initializeSchema 布尔值,或在application.properties 文件中设置…​initialize-schema=true

请参阅依赖项管理 部分,将 Spring AI BOM 添加到您的构建文件中。
请参阅存储库 部分,将里程碑和/或快照存储库添加到您的构建文件中。

模式初始化

向量存储实现可以为您初始化必要的模式,但您必须选择加入,方法是在相应的构造函数中指定initializeSchema 布尔值,或在application.properties 文件中设置spring.ai.vectorstore.mongodb.initialize-schema=true

这是一个重大更改!在早期版本的 Spring AI 中,此模式初始化默认启用。

initializeSchema 设置为true 时,将自动执行以下操作

  • **集合创建**:如果指定的用于存储向量的集合不存在,则会创建它。

  • **搜索索引创建**:将根据配置属性创建搜索索引。

如果您运行的是免费层或共享层集群,则必须通过 Atlas UI、Atlas 管理 API 或 Atlas CLI 单独创建索引。

如果您在springai_test.vector_store 集合上拥有名为vector_index 的现有 Atlas 向量搜索索引,Spring AI 不会创建其他索引。因此,如果现有索引配置了不兼容的设置(例如,维度数量不同),您以后可能会遇到错误。

确保您的索引具有以下配置

{
  "fields": [
    {
      "numDimensions": 1536,
      "path": "embedding",
      "similarity": "cosine",
      "type": "vector"
    }
  ]
}

此外,您还需要一个已配置的EmbeddingModel bean。有关更多信息,请参阅EmbeddingModel 部分。

以下是一个所需 bean 的示例

@Bean
public EmbeddingModel embeddingModel() {
    // Can be any other EmbeddingModel implementation.
    return new OpenAiEmbeddingModel(new OpenAiApi(System.getenv("SPRING_AI_OPENAI_API_KEY")));
}

配置属性

您可以在 Spring Boot 配置中使用以下属性来自定义 MongoDB Atlas 向量存储。

...
spring.data.mongodb.uri=<connection string>
spring.data.mongodb.database=<database name>

spring.ai.vectorstore.mongodb.collection-name=vector_store
spring.ai.vectorstore.mongodb.initialize-schema=true
spring.ai.vectorstore.mongodb.path-name=embedding
spring.ai.vectorstore.mongodb.indexName=vector_index
spring.ai.vectorstore.mongodb.metadata-fields-to-filter=foo
属性 描述 默认值

spring.ai.vectorstore.mongodb.collection-name

用于存储向量的集合的名称。

vector_store

spring.ai.vectorstore.mongodb.initialize-schema

是否为您初始化后端模式

false

spring.ai.vectorstore.mongodb.path-name

用于存储向量的路径的名称。

embedding

spring.ai.vectorstore.mongodb.indexName

用于存储向量的索引的名称。

vector_index

spring.ai.vectorstore.mongodb.metadata-fields-to-filter

逗号分隔的值,指定查询向量存储时可以使用哪些元数据字段进行过滤。如果元数据索引尚不存在,则需要创建它们。

空列表

手动配置属性

如果您更喜欢手动配置 MongoDB Atlas 向量存储而无需自动配置,则可以通过直接设置MongoDBAtlasVectorStore 及其依赖项来实现。

示例配置

@Configuration
public class VectorStoreConfig {

    @Bean
    public MongoDBAtlasVectorStore vectorStore(MongoTemplate mongoTemplate, EmbeddingModel embeddingModel) {
        MongoDBVectorStoreConfig config = MongoDBVectorStoreConfig.builder()
            .withCollectionName("custom_vector_store")
            .withVectorIndexName("custom_vector_index")
            .withPathName("custom_embedding_path")
            .withMetadataFieldsToFilter(List.of("author", "year"))
            .build();

        return new MongoDBAtlasVectorStore(mongoTemplate, embeddingModel, config, true);
    }
}

属性

  • collectionName:用于存储向量的集合的名称。

  • vectorIndexName:向量索引的名称。

  • pathName:存储向量的路径。

  • metadataFieldsToFilter:要过滤的元数据字段列表。

您可以通过在MongoDBAtlasVectorStore 构造函数中将true作为最后一个参数传递来启用模式初始化

添加文档

要将文档添加到向量数据库,您需要将输入文档转换为Document类型并调用addDocuments()方法。此方法将使用EmbeddingModel计算嵌入并将其保存到MongoDB集合中。

List<Document> docs = List.of(
	new Document("Proper tuber planting involves site selection, timing, and care. Choose well-drained soil and adequate sun exposure. Plant in spring, with eyes facing upward at a depth two to three times the tuber's height. Ensure 4-12 inch spacing based on tuber size. Adequate moisture is needed, but avoid overwatering. Mulching helps preserve moisture and prevent weeds.", Map.of("author", "A", "type", "post")),
	new Document("Successful oil painting requires patience, proper equipment, and technique. Prepare a primed canvas, sketch lightly, and use high-quality brushes and oils. Paint 'fat over lean' to prevent cracking. Allow each layer to dry before applying the next. Clean brushes often and work in a well-ventilated space.", Map.of("author", "A")),
	new Document("For a natural lawn, select the right grass type for your climate. Water 1 to 1.5 inches per week, avoid overwatering, and use organic fertilizers. Regular aeration helps root growth and prevents compaction. Practice natural pest control and overseeding to maintain a dense lawn.", Map.of("author", "B", "type", "post")) );

vectorStore.add(docs);

删除文档

要从向量数据库中删除文档,请使用delete()方法。此方法接受文档 ID 列表,并从 MongoDB 集合中删除相应的文档。

List<String> ids = List.of("id1", "id2", "id3"); // Replace with actual document IDs

vectorStore.delete(ids);

要执行相似性搜索,请使用所需的查询参数构造一个SearchRequest对象并调用similaritySearch()方法。此方法将返回基于向量相似性与查询匹配的文档列表。

List<Document> results = vectorStore.similaritySearch(
            SearchRequest
                    .query("learn how to grow things")
                    .withTopK(2)
    );

元数据过滤

元数据过滤允许通过基于指定的元数据字段过滤结果来进行更精确的查询。此功能使用 MongoDB 查询 API 来执行与向量搜索结合的过滤操作。

过滤器表达式

MongoDBAtlasFilterExpressionConverter类将过滤器表达式转换为MongoDB Atlas元数据过滤器表达式。支持的操作包括

  • $and

  • $or

  • $eq

  • $ne

  • $lt

  • $lte

  • $gt

  • $gte

  • $in

  • $nin

这些操作使过滤逻辑能够应用于与向量数据库中文档关联的元数据字段。

过滤器表达式的示例

以下是如何在相似性搜索中使用过滤器表达式的示例

FilterExpressionBuilder b = new FilterExpressionBuilder();

List<Document> results = vectorStore.similaritySearch(
        SearchRequest.defaults()
                .withQuery("learn how to grow things")
                .withTopK(2)
                .withSimilarityThreshold(0.5)
                .withFilterExpression(this.b.eq("author", "A").build())
);

教程和代码示例

开始使用 Spring AI 和 MongoDB