Azure Cosmos DB
本节将引导您设置 CosmosDBVectorStore
以存储文档嵌入并执行相似性搜索。
什么是 Azure Cosmos DB?
Azure Cosmos DB 是微软的全球分布式云原生数据库服务,专为关键任务应用程序而设计。它提供高可用性、低延迟以及能够水平扩展以满足现代应用程序需求的功能。它从一开始就以全球分布、细粒度多租户和横向扩展为核心构建。它是 Azure 中的一项基础服务,被微软的大多数全球关键任务应用程序使用,包括 Teams、Skype、Xbox Live、Office 365、Bing、Azure Active Directory、Azure 门户、Microsoft Store 等等。它也被数千家外部客户使用,包括 OpenAI 用于 ChatGPT 和其他需要弹性扩展、交钥匙全球分布以及全球范围内低延迟和高可用性的关键任务 AI 应用程序。
什么是 DiskANN?
DiskANN(基于磁盘的近似最近邻搜索)是 Azure Cosmos DB 中使用的一项创新技术,用于增强向量搜索的性能。它通过索引存储在 Cosmos DB 中的嵌入,能够对高维数据进行高效且可扩展的相似性搜索。
DiskANN 提供以下优势
-
效率:通过利用基于磁盘的结构,与传统方法相比,DiskANN 显着减少了查找最近邻所需的时间。
-
可扩展性:它可以处理超出内存容量的大型数据集,使其适用于各种应用程序,包括机器学习和 AI 驱动的解决方案。
-
低延迟:DiskANN 在搜索操作期间最大程度地减少延迟,确保应用程序即使在大量数据的情况下也能快速检索结果。
在用于 Azure Cosmos DB 的 Spring AI 的上下文中,向量搜索将创建并利用 DiskANN 索引以确保相似性查询的最佳性能。
使用自动配置设置 Azure Cosmos DB 向量存储
以下代码演示了如何使用自动配置设置 CosmosDBVectorStore
package com.example.demo;
import io.micrometer.observation.ObservationRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootApplication
@EnableAutoConfiguration
public class DemoApplication implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(DemoApplication.class);
@Lazy
@Autowired
private VectorStore vectorStore;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Document document1 = new Document(UUID.randomUUID().toString(), "Sample content1", Map.of("key1", "value1"));
Document document2 = new Document(UUID.randomUUID().toString(), "Sample content2", Map.of("key2", "value2"));
this.vectorStore.add(List.of(document1, document2));
List<Document> results = this.vectorStore.similaritySearch(SearchRequest.query("Sample content").withTopK(1));
log.info("Search results: {}", results);
// Remove the documents from the vector store
this.vectorStore.delete(List.of(document1.getId(), document2.getId()));
}
@Bean
public ObservationRegistry observationRegistry() {
return ObservationRegistry.create();
}
}
自动配置
将以下依赖项添加到您的 Maven 项目中
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-azure-cosmos-db-store-spring-boot-starter</artifactId>
</dependency>
配置属性
以下配置属性可用于 Cosmos DB 向量存储
属性 | 描述 |
---|---|
spring.ai.vectorstore.cosmosdb.databaseName |
要使用的 Cosmos DB 数据库的名称。 |
spring.ai.vectorstore.cosmosdb.containerName |
要使用的 Cosmos DB 容器的名称。 |
spring.ai.vectorstore.cosmosdb.partitionKeyPath |
分区键的路径。 |
spring.ai.vectorstore.cosmosdb.metadataFields |
元数据字段的逗号分隔列表。 |
spring.ai.vectorstore.cosmosdb.vectorStoreThroughput |
向量存储的吞吐量。 |
spring.ai.vectorstore.cosmosdb.vectorDimensions |
向量的维度数。 |
spring.ai.vectorstore.cosmosdb.endpoint |
Cosmos DB 的端点。 |
spring.ai.vectorstore.cosmosdb.key |
Cosmos DB 的密钥。 |
使用过滤器进行复杂搜索
您可以使用 Cosmos DB 向量存储中的过滤器执行更复杂的搜索。下面是一个示例,演示了如何在搜索查询中使用过滤器。
Map<String, Object> metadata1 = new HashMap<>();
metadata1.put("country", "UK");
metadata1.put("year", 2021);
metadata1.put("city", "London");
Map<String, Object> metadata2 = new HashMap<>();
metadata2.put("country", "NL");
metadata2.put("year", 2022);
metadata2.put("city", "Amsterdam");
Document document1 = new Document("1", "A document about the UK", this.metadata1);
Document document2 = new Document("2", "A document about the Netherlands", this.metadata2);
vectorStore.add(List.of(document1, document2));
FilterExpressionBuilder builder = new FilterExpressionBuilder();
List<Document> results = vectorStore.similaritySearch(SearchRequest.query("The World")
.withTopK(10)
.withFilterExpression((this.builder.in("country", "UK", "NL")).build()));
不使用自动配置设置 Azure Cosmos DB 向量存储
以下代码演示了如何在不依赖自动配置的情况下设置 CosmosDBVectorStore
package com.example.demo;
import com.azure.cosmos.CosmosAsyncClient;
import com.azure.cosmos.CosmosClientBuilder;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.transformers.TransformersEmbeddingModel;
import org.springframework.ai.vectorstore.CosmosDBVectorStore;
import org.springframework.ai.vectorstore.CosmosDBVectorStoreConfig;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Lazy
@Autowired
private VectorStore vectorStore;
@Lazy
@Autowired
private EmbeddingModel embeddingModel;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Document document1 = new Document(UUID.randomUUID().toString(), "Sample content1", Map.of("key1", "value1"));
Document document2 = new Document(UUID.randomUUID().toString(), "Sample content2", Map.of("key2", "value2"));
this.vectorStore.add(List.of(document1, document2));
List<Document> results = this.vectorStore.similaritySearch(SearchRequest.query("Sample content").withTopK(1));
log.info("Search results: {}", results);
}
@Bean
public ObservationRegistry observationRegistry() {
return ObservationRegistry.create();
}
@Bean
public VectorStore vectorStore(ObservationRegistry observationRegistry) {
CosmosDBVectorStoreConfig config = new CosmosDBVectorStoreConfig();
config.setDatabaseName("spring-ai-sample");
config.setContainerName("container");
config.setMetadataFields("country,city");
config.setVectorStoreThroughput(400);
CosmosAsyncClient cosmosClient = new CosmosClientBuilder()
.endpoint(System.getenv("COSMOSDB_AI_ENDPOINT"))
.userAgentSuffix("SpringAI-CDBNoSQL-VectorStore")
.key(System.getenv("COSMOSDB_AI_KEY"))
.gatewayMode()
.buildAsyncClient();
return new CosmosDBVectorStore(observationRegistry, null, cosmosClient, config, this.embeddingModel);
}
@Bean
public EmbeddingModel embeddingModel() {
return new TransformersEmbeddingModel();
}
}