Azure Cosmos DB NoSQL 向量数据库
Spring AI 支持使用 Azure Cosmos DB for NoSQL 作为向量数据库,通过其向量嵌入和索引功能。
先决条件
- Azure 账户:您需要一个拥有有效订阅的 Azure 账户。
- Azure Cosmos DB for NoSQL 资源:在您的 Azure 账户中创建一个 Azure Cosmos DB for NoSQL 账户。
- 在创建过程中,请确保选择”NoSQL” API。
- 记下您的 Cosmos DB 端点和主密钥,因为在应用程序配置中将会用到它们。
- 向量嵌入功能:目前,Azure Cosmos DB for NoSQL 中的向量搜索功能处于预览阶段。您需要按照这些说明注册预览版。
添加依赖
将 spring-ai-azure-cosmos-db-store-spring-boot-starter
依赖项添加到您的 pom.xml
文件中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-azure-cosmos-db-store-spring-boot-starter</artifactId>
</dependency>
您还需要一个 EmbeddingClient
实现来为您的文档生成向量嵌入。例如,您可以添加 spring-ai-openai-spring-boot-starter
以使用 OpenAI 的嵌入模型:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
配置属性
在您的 application.properties
或 application.yml
文件中配置 Azure Cosmos DB 和嵌入客户端属性。
Azure Cosmos DB 属性
# Azure Cosmos DB 配置
spring.ai.vectorstore.cosmosdb.endpoint=YOUR_COSMOS_DB_ENDPOINT # 例如 https://your-account.documents.azure.com:443/
spring.ai.vectorstore.cosmosdb.key=YOUR_COSMOS_DB_PRIMARY_KEY
spring.ai.vectorstore.cosmosdb.database-name=your_database_name
spring.ai.vectorstore.cosmosdb.container-name=your_container_name # 将在其中存储向量的容器
spring.ai.vectorstore.cosmosdb.create-container-if-not-exists=true # 如果容器不存在则创建 (可选, 默认为 false)
# 向量索引策略 (在容器创建时应用)
spring.ai.vectorstore.cosmosdb.indexing-policy.vector-indexes[0].path="/embedding" # JSON 文档中包含向量的路径
spring.ai.vectorstore.cosmosdb.indexing-policy.vector-indexes[0].type="vector-ivf" # 索引类型,例如 vector-ivf, vector-hnsw
spring.ai.vectorstore.cosmosdb.indexing-policy.vector-indexes[0].num-lists=1 # 对于 IVF (默认为 1)
spring.ai.vectorstore.cosmosdb.indexing-policy.vector-indexes[0].dimensions=1536 # 嵌入向量的维度 (例如 OpenAI text-embedding-ada-002 为 1536)
spring.ai.vectorstore.cosmosdb.indexing-policy.vector-indexes[0].distance-function="cosine" # 距离函数,例如 cosine, euclidean, dotproduct
如果 create-container-if-not-exists
设置为 true
,则当容器尚不存在时,将使用提供的 indexing-policy
创建它。
如果容器已存在,则现有索引策略将保持不变,并且提供的 indexing-policy
配置将被忽略。
确保嵌入客户端输出的维度与索引策略中配置的 dimensions
匹配。
嵌入客户端属性 (例如 OpenAI)
# OpenAI EmbeddingClient 配置
spring.ai.openai.api-key=YOUR_OPENAI_API_KEY
spring.ai.openai.embedding.options.model=text-embedding-ada-002
使用 VectorStore
将 VectorStore
bean 注入到您的组件中以与之交互:
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.document.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MyVectorStoreService {
private final VectorStore vectorStore;
@Autowired
public MyVectorStoreService(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
public void addDocuments(List<Document> documents) {
vectorStore.add(documents);
}
public List<Document> findSimilarDocuments(String query, int k) {
return vectorStore.similaritySearch(query, k);
}
}
创建 CosmosDBVectorStore
Bean (可选)
Spring Boot 会自动配置 CosmosDBVectorStore
bean。但是,如果您需要自定义配置,可以定义自己的 bean:
import com.azure.cosmos.CosmosAsyncClient;
import com.azure.cosmos.CosmosClientBuilder;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.azure.cosmosdb.CosmosDBVectorStore;
import org.springframework.ai.vectorstore.azure.cosmosdb.CosmosDBVectorStoreConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyCosmosDbConfig {
@Bean
public CosmosAsyncClient cosmosAsyncClient() {
// 从属性或直接创建 CosmosAsyncClient
return new CosmosClientBuilder()
.endpoint("YOUR_COSMOS_DB_ENDPOINT")
.key("YOUR_COSMOS_DB_PRIMARY_KEY")
.buildAsyncClient();
}
@Bean
public CosmosDBVectorStore cosmosDBVectorStore(CosmosAsyncClient cosmosAsyncClient, EmbeddingClient embeddingClient) {
CosmosDBVectorStoreConfig config = CosmosDBVectorStoreConfig.builder("your_database_name", "your_container_name")
// .createContainerIfNotExists(true) // 按需设置
// .indexingPolicy(...) // 按需设置索引策略
.build();
return new CosmosDBVectorStore(cosmosAsyncClient, embeddingClient, config);
}
}
向量索引
Azure Cosmos DB for NoSQL 支持多种类型的向量索引,例如 vector-ivf
和 vector-hnsw
。索引的选择取决于您的特定用例和性能要求。
vector-ivf
(Inverted File Index):适用于大型数据集,并在准确性和查询速度之间提供良好的平衡。它将向量空间划分为簇,并在查询时仅搜索最相关的簇。
vector-hnsw
(Hierarchical Navigable Small World):一种基于图的索引,以其高查询召回率和低延迟而闻名,尤其适用于高维数据。
您可以在 application.properties
中的 spring.ai.vectorstore.cosmosdb.indexing-policy.vector-indexes
下或在以编程方式配置 CosmosDBVectorStoreConfig
时配置索引类型、维度、距离函数和特定于类型的参数 (例如 num-lists
for IVF)。
// 示例索引策略 JSON
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
}
],
"vectorIndexes": [
{
"path": "/embedding", // 确保这与您的文档结构匹配
"type": "vector-ivf",
"numLists": 1,
"dimensions": 1536,
"distanceFunction": "cosine"
}
]
}
元数据过滤
Cosmos DB 向量存储支持使用 SQL WHERE子句 和 相似性搜索过滤器表达式 进行元数据过滤。这些过滤器应用于相似性搜索查询期间,以根据其元数据字段缩小结果范围。
过滤器表达式直接转换为 Cosmos DB SQL WHERE 子句。
例如,如果您有带有元数据字段 genre
和 year
的文档,则可以按如下方式进行过滤:
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.filter.Filter;
import org.springframework.ai.vectorstore.filter.FilterExpressionBuilder;
// ...
FilterExpressionBuilder b = new FilterExpressionBuilder();
// WHERE genre = 'drama' AND year > 2020
Filter filter = new Filter(b.eq("genre", "drama").and(b.gt("year", 2020)).build());
SearchRequest request = SearchRequest.query("A tragic hero") // 示例查询通常保留英文
.withTopK(5)
.withSimilarityThreshold(0.75)
.withFilter(filter);
List<Document> results = vectorStore.similaritySearch(request);
这将转换为类似于以下的 Cosmos DB 查询:
SELECT c.id, c.content, c.metadata, VectorDistance(c.embedding, @embeddingParam) AS similarity
FROM c
WHERE c.metadata.genre = 'drama' AND c.metadata.year > 2020
ORDER BY VectorDistance(c.embedding, @embeddingParam)
确保您的容器中存在用于过滤的元数据字段,并且它们已正确索引 (如果需要提高性能)。
并非所有 Spring AI 过滤器表达式操作符都直接映射到 Cosmos DB SQL 函数。支持基本比较 (EQ
, NE
, GT
, GTE
, LT
, LTE
)、逻辑运算符 (AND
, OR
, NOT
) 和 IN
/ NIN
。
删除数据
CosmosDBVectorStore
支持通过文档 ID 删除数据。
boolean deleted = vectorStore.delete(List.of("documentId1", "documentId2"));
通过将 Spring AI 与 Azure Cosmos DB for NoSQL 集成,您可以利用 Azure 的可扩展且全球分布的数据库服务来满足您的向量存储需求,并结合 Spring AI 的简化抽象来构建强大的 AI 应用程序。
文档有误?请协助编辑
发现文档问题?点击此处直接在 GitHub 上编辑并提交 PR,帮助我们改进文档!