> ## 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.

# Typesense 向量数据库

# Typesense 向量数据库

Spring AI 支持将 [Typesense](https://typesense.org/) 作为向量数据库。

## 添加依赖

要使用 Typesense 向量存储，您需要将 `spring-ai-typesense-store-spring-boot-starter` 依赖项添加到项目的 `pom.xml` 文件中。
该启动器包含了 `spring-ai-core` 和 Typesense Java 客户端库。

```xml theme={"system"}
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-typesense-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` 文件中配置 Typesense 和嵌入客户端属性。

### Typesense 属性

| 属性                                                    | 描述                                           | 默认值                                  |
| :---------------------------------------------------- | :------------------------------------------- | :----------------------------------- |
| `spring.ai.vectorstore.typesense.collection-name`     | 用于存储文档的 Typesense 集合名称。                      | `spring_ai_collection`               |
| `spring.ai.vectorstore.typesense.embedding-dimension` | 嵌入向量的维度。必须与 `EmbeddingClient` 生成的维度匹配。       | 1536 (OpenAI text-embedding-ada-002) |
| `spring.ai.vectorstore.typesense.host`                | Typesense 服务器的主机名或 IP 地址。                    | `localhost`                          |
| `spring.ai.vectorstore.typesense.port`                | Typesense 服务器的端口。                            | `8108`                               |
| `spring.ai.vectorstore.typesense.protocol`            | 用于连接到 Typesense 服务器的协议 (例如 `http` 或 `https`) | `http`                               |
| `spring.ai.vectorstore.typesense.api-key`             | 用于向 Typesense 服务器进行身份验证的 API 密钥。             |                                      |

**示例 `application.properties`:**

```properties theme={"system"}
# Typesense 配置
spring.ai.vectorstore.typesense.collection-name=my_documents
spring.ai.vectorstore.typesense.embedding-dimension=1536
spring.ai.vectorstore.typesense.host=localhost
spring.ai.vectorstore.typesense.port=8108
spring.ai.vectorstore.typesense.protocol=http
spring.ai.vectorstore.typesense.api-key=YOUR_TYPESENSE_API_KEY

# 嵌入客户端配置 (例如 OpenAI)
spring.ai.openai.api-key=YOUR_OPENAI_API_KEY
spring.ai.openai.embedding.options.model=text-embedding-ada-002
```

<Note>
  确保 `spring.ai.vectorstore.typesense.embedding-dimension` 与您正在使用的 `EmbeddingClient` 输出的嵌入维度相匹配。
</Note>

## 使用 `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; // 将自动配置 TypesenseVectorStore

    @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);
    }
}
```

### 创建 `TypesenseVectorStore` Bean (可选)

Spring Boot 会自动配置 `TypesenseVectorStore` bean。但是，如果您需要自定义配置，可以定义自己的 bean：

```java theme={"system"}
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.TypesenseVectorStore;
import org.springframework.ai.vectorstore.TypesenseVectorStore.TypesenseVectorStoreConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.typesense.api.Client;
import org.typesense.api.ConfigurationNode;

import java.util.List;

@Configuration
public class MyTypesenseConfig {

    @Bean
    public Client typesenseClient() {
        // 从属性或直接创建 TypesenseClient
        List<ConfigurationNode> nodes = List.of(
            new ConfigurationNode("localhost", "8108", "http")
        );
        // 如果需要 API 密钥:
        // org.typesense.api.Configuration configuration = new org.typesense.api.Configuration(nodes, java.time.Duration.ofSeconds(10), "YOUR_TYPESENSE_API_KEY");
        org.typesense.api.Configuration configuration = new org.typesense.api.Configuration(nodes, java.time.Duration.ofSeconds(10), "YOUR_TYPESENSE_API_KEY");
        return new Client(configuration);
    }

    @Bean
    public TypesenseVectorStore typesenseVectorStore(Client typesenseClient, EmbeddingClient embeddingClient) {
        TypesenseVectorStoreConfig config = TypesenseVectorStoreConfig.builder()
            .withCollectionName("my_custom_collection")
            .withEmbeddingDimension(1536)
            .build();
        return new TypesenseVectorStore(typesenseClient, embeddingClient, config);
    }
}
```

## 元数据过滤

Typesense 向量存储支持使用 [Typesense 的 filter\_by 查询参数](https://typesense.org/docs/0.25.2/api/vector-search.html#filter-results) 和 Spring AI 的 [相似性搜索过滤器表达式](./index.mdx#metadata-filtering) 进行元数据过滤。

过滤器表达式会转换为 Typesense 的 `filter_by` 字符串格式。

**示例：**

```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();

// genre:='drama' && year:>2020
Filter filter = new Filter(b.eq("genre", "drama").and(b.gt("year", 2020)).build());

SearchRequest request = SearchRequest.query("A dramatic film released after 2020") // 示例查询通常保留英文
    .withTopK(5)
    .withFilter(filter);

List<Document> results = vectorStore.similaritySearch(request);
```

<Note>
  确保用于过滤的元数据字段存在于您的 Typesense 集合 schema 中，并根据 Typesense 的要求进行适当定义 (例如，将它们定义为 `facet: true` 以进行高效过滤)。
  Typesense 对 `filter_by` 语法有特定的要求。Spring AI 的 `FilterExpressionConverter` 尽力将其转换为兼容的格式，但复杂的嵌套表达式可能无法完全支持或需要仔细构建。
</Note>

## 删除数据

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

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

## 总结

将 Spring AI 与 Typesense 集成，提供了一种快速且易于使用的向量搜索解决方案，利用了 Typesense 的内存性能和对开发人员友好的特性。

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