> ## Documentation Index
> Fetch the complete documentation index at: https://javaai.pig4cloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Azure Cosmos DB 向量数据库

# Azure Cosmos DB NoSQL 向量数据库

Spring AI 支持使用 [Azure Cosmos DB for NoSQL](https://learn.microsoft.com/azure/cosmos-db/nosql/) 作为向量数据库，通过其向量嵌入和索引功能。

## 先决条件

1. **Azure 账户**：您需要一个拥有有效订阅的 Azure 账户。
2. **Azure Cosmos DB for NoSQL 资源**：在您的 Azure 账户中创建一个 Azure Cosmos DB for NoSQL 账户。
   * 在创建过程中，请确保选择"NoSQL" API。
   * 记下您的 Cosmos DB 端点和主密钥，因为在应用程序配置中将会用到它们。
3. **向量嵌入功能**：目前，Azure Cosmos DB for NoSQL 中的向量搜索功能处于预览阶段。您需要按照[这些说明](https://learn.microsoft.com/azure/cosmos-db/nosql/vector-search#register-for-the-preview-of-vector-search-in-azure-cosmos-db-for-nosql)注册预览版。

## 添加依赖

将 `spring-ai-azure-cosmos-db-store-spring-boot-starter` 依赖项添加到您的 `pom.xml` 文件中：

```xml theme={"system"}
<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 的嵌入模型：

```xml theme={"system"}
<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 属性

```properties theme={"system"}
# 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
```

<Note>
  如果 `create-container-if-not-exists` 设置为 `true`，则当容器尚不存在时，将使用提供的 `indexing-policy` 创建它。
  如果容器已存在，则现有索引策略将保持不变，并且提供的 `indexing-policy` 配置将被忽略。
  确保嵌入客户端输出的维度与索引策略中配置的 `dimensions` 匹配。
</Note>

### 嵌入客户端属性 (例如 OpenAI)

```properties theme={"system"}
# OpenAI EmbeddingClient 配置
spring.ai.openai.api-key=YOUR_OPENAI_API_KEY
spring.ai.openai.embedding.options.model=text-embedding-ada-002
```

## 使用 `VectorStore`

将 `VectorStore` bean 注入到您的组件中以与之交互：

```java theme={"system"}
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：

```java theme={"system"}
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 theme={"system"}
// 示例索引策略 JSON
{
  "indexingMode": "consistent",
  "automatic": true,
  "includedPaths": [
    {
      "path": "/*"
    }
  ],
  "excludedPaths": [
    {
      "path": "/\"_etag\"/?"
    }
  ],
  "vectorIndexes": [
    {
      "path": "/embedding", // 确保这与您的文档结构匹配
      "type": "vector-ivf",
      "numLists": 1,
      "dimensions": 1536,
      "distanceFunction": "cosine"
    }
  ]
}
```

<Tip>
  有关向量索引的更多详细信息，请参阅 [Azure Cosmos DB for NoSQL 向量索引文档](https://learn.microsoft.com/azure/cosmos-db/nosql/vector-search#vector-indexing-policies)。
</Tip>

## 元数据过滤

Cosmos DB 向量存储支持使用 [SQL WHERE子句](https://learn.microsoft.com/azure/cosmos-db/nosql/query/where) 和 [相似性搜索过滤器表达式](./../index.mdx#metadata-filtering) 进行元数据过滤。这些过滤器应用于相似性搜索查询期间，以根据其元数据字段缩小结果范围。

过滤器表达式直接转换为 Cosmos DB SQL WHERE 子句。

例如，如果您有带有元数据字段 `genre` 和 `year` 的文档，则可以按如下方式进行过滤：

```java theme={"system"}
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 查询：

```sql theme={"system"}
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)
```

<Note>
  确保您的容器中存在用于过滤的元数据字段，并且它们已正确索引 (如果需要提高性能)。
  并非所有 Spring AI 过滤器表达式操作符都直接映射到 Cosmos DB SQL 函数。支持基本比较 (`EQ`, `NE`, `GT`, `GTE`, `LT`, `LTE`)、逻辑运算符 (`AND`, `OR`, `NOT`) 和 `IN` / `NIN`。
</Note>

## 删除数据

`CosmosDBVectorStore` 支持通过文档 ID 删除数据。

```java theme={"system"}
boolean deleted = vectorStore.delete(List.of("documentId1", "documentId2"));
```

## 总结

通过将 Spring AI 与 Azure Cosmos DB for NoSQL 集成，您可以利用 Azure 的可扩展且全球分布的数据库服务来满足您的向量存储需求，并结合 Spring AI 的简化抽象来构建强大的 AI 应用程序。

<Card title="文档有误？请协助编辑" icon="pencil" href="https://github.com/javaai-pig4cloud-com/javaai-docs/edit/main/spring-ai/api/vectordbs/azure-cosmos-db.mdx">
  发现文档问题？点击此处直接在 GitHub 上编辑并提交 PR，帮助我们改进文档！
</Card>
