Typesense
本节将指导您如何设置 TypesenseVectorStore 来存储文档嵌入向量并执行相似性搜索。
Typesense 是一款开源的容错搜索引擎,专为瞬时(低于50毫秒)搜索而优化,同时提供直观的开发者体验。它提供向量搜索功能,使您能够存储和查询高维向量,并可与常规搜索数据结合使用。
前提条件
-
一个正在运行的 Typesense 实例。有以下选项可供选择:
-
Typesense Cloud(推荐)
-
Docker 镜像 typesense/typesense:latest,来自 Docker Hub
-
-
如果需要,为 EmbeddingModel 准备一个 API 密钥,用于生成由
TypesenseVectorStore存储的嵌入向量。
自动配置
Spring AI 自动配置和 starter 模块的 artifact 名称发生了重大变化。更多信息请参阅升级说明。
Spring AI 为 Typesense 向量存储提供了 Spring Boot 自动配置。要启用它,请将以下依赖项添加到您项目的 Maven pom.xml 文件中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-typesense</artifactId>
</dependency>
或添加到您的 Gradle build.gradle 构建文件中。
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-vector-store-typesense'
}
请参考 依赖管理 部分,将 Spring AI BOM 添加到你的构建文件中。
请查看向量存储的配置参数列表,了解默认值和配置选项。
:::提示
请参考构件仓库部分,将Maven Central 和/或快照仓库添加到你的构建文件中。
:::
向量存储的实现可以为您初始化必要的模式,但您必须通过在 application.properties 文件中设置 …initialize-schema=true 来选择启用。
此外,您还需要一个已配置的 EmbeddingModel bean。有关更多信息,请参阅 EmbeddingModel 部分。
现在,你可以在应用中自动装配 TypesenseVectorStore 作为向量存储:
@Autowired VectorStore vectorStore;
// ...
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
new Document("The World is Big and Salvation Lurks Around the Corner"),
new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));
// Add the documents to Typesense
vectorStore.add(documents);
// Retrieve documents similar to a query
List<Document> results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());
配置属性
要连接到Typesense并使用TypesenseVectorStore,您需要提供实例的访问信息。可以通过Spring Boot的application.yml提供简单的配置:
spring:
ai:
vectorstore:
typesense:
initialize-schema: true
collection-name: vector_store
embedding-dimension: 1536
client:
protocol: http
host: localhost
port: 8108
api-key: xyz
以 spring.ai.vectorstore.typesense.* 开头的属性用于配置 TypesenseVectorStore:
| 属性 | 描述 | 默认值 |
|---|---|---|
spring.ai.vectorstore.typesense.initialize-schema | 是否初始化所需的模式 | false |
spring.ai.vectorstore.typesense.collection-name | 用于存储向量的集合名称 | vector_store |
spring.ai.vectorstore.typesense.embedding-dimension | 向量的维度数量 | 1536 |
spring.ai.vectorstore.typesense.client.protocol | HTTP 协议 | http |
spring.ai.vectorstore.typesense.client.host | 主机名 | localhost |
spring.ai.vectorstore.typesense.client.port | 端口 | 8108 |
spring.ai.vectorstore.typesense.client.api-key | API 密钥 | xyz |
手动配置
除了使用 Spring Boot 的自动配置外,你也可以手动配置 Typesense 向量存储。为此,你需要在项目中添加 spring-ai-typesense-store 依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-typesense-store</artifactId>
</dependency>
或将其添加到您的 Gradle build.gradle 构建文件中。
dependencies {
implementation 'org.springframework.ai:spring-ai-typesense-store'
}
:::提示
请参考依赖管理章节,将Spring AI BOM添加到您的构建文件中。
:::
创建一个Typesense Client bean:
@Bean
public Client typesenseClient() {
List<Node> nodes = new ArrayList<>();
nodes.add(new Node("http", "localhost", "8108"));
Configuration configuration = new Configuration(nodes, Duration.ofSeconds(5), "xyz");
return new Client(configuration);
}
随后使用构建器模式创建 TypesenseVectorStore bean:
@Bean
public VectorStore vectorStore(Client client, EmbeddingModel embeddingModel) {
return TypesenseVectorStore.builder(client, embeddingModel)
.collectionName("custom_vectors") // Optional: defaults to "vector_store"
.embeddingDimension(1536) // Optional: defaults to 1536
.initializeSchema(true) // Optional: defaults to false
.batchingStrategy(new TokenCountBatchingStrategy()) // Optional: defaults to TokenCountBatchingStrategy
.build();
}
// This can be any EmbeddingModel implementation
@Bean
public EmbeddingModel embeddingModel() {
return new OpenAiEmbeddingModel(new OpenAiApi(System.getenv("OPENAI_API_KEY")));
}
元数据筛选
您也可以将通用的便携式元数据过滤器与Typesense存储结合使用。
例如,您可以使用文本表达式语言:
vectorStore.similaritySearch(
SearchRequest.builder()
.query("The World")
.topK(TOP_K)
.similarityThreshold(SIMILARITY_THRESHOLD)
.filterExpression("country in ['UK', 'NL'] && year >= 2020").build());
或者通过编程方式使用 Filter.Expression DSL:
FilterExpressionBuilder b = new FilterExpressionBuilder();
vectorStore.similaritySearch(SearchRequest.builder()
.query("The World")
.topK(TOP_K)
.similarityThreshold(SIMILARITY_THRESHOLD)
.filterExpression(b.and(
b.in("country", "UK", "NL"),
b.gte("year", 2020)).build()).build());
这些(可移植的)过滤器表达式会自动转换为 Typesense 搜索过滤器。
例如这个便携式过滤器表达式:
country in ['UK', 'NL'] && year >= 2020
转换为专有的 Typesense 过滤器格式:
country: ['UK', 'NL'] && year: >=2020
如果您没有按预期顺序检索文档,或者搜索结果不符合预期,请检查您正在使用的嵌入模型。
嵌入模型可能对搜索结果产生重大影响(例如,请确保如果您的数据是西班牙语,请使用西班牙语或多语言嵌入模型)。
访问原生客户端
Typesense向量存储实现通过getNativeClient()方法提供了对底层原生Typesense客户端(Client)的访问:
TypesenseVectorStore vectorStore = context.getBean(TypesenseVectorStore.class);
Optional<Client> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
Client client = nativeClient.get();
// Use the native client for Typesense-specific operations
}
原生客户端让您能够访问Typesense特有的功能和操作,这些可能未通过VectorStore接口公开。