Core API
VectorStore 是向量数据库的统一抽象,提供文档存储、相似度搜索与元数据过滤能力。通过 add() 写入文档,similaritySearch() 检索,支持 20 种向量数据库实现。
2. 核心操作
VectorStore 继承 DocumentWriter(即 Consumer<List<Document>>),定义了三类核心操作。
方法说明:
| 方法 | 参数 | 说明 |
|---|---|---|
add | List<Document> | 批量添加文档,底层自动调用 EmbeddingModel 生成向量后存储 |
delete | List<String> | 按文档 ID 列表删除 |
delete | Filter.Expression | 按条件表达式批量删除(需厂商支持) |
similaritySearch | SearchRequest | 将查询文本向量化后执行相似度搜索,返回匹配的文档列表 |
similaritySearch | String | 便捷方法,仅指定查询文本,其余参数使用默认值 |
getNativeClient | - | 获取底层原生客户端(如 JdbcTemplate、JedisPooled),用于高级操作 |
3. 文档数据结构
Document 是 VectorStore 中存储的最小数据单元,包含文本或媒体内容及其元数据。
构造方式:
- 纯文本
- 文本+元数据
- Builder 方式(推荐)
// 仅文本
Document doc1 = new Document("Spring AI 是一个 AI 集成框架");
// 文本 + 元数据
Document doc2 = new Document("内容文本",
Map.of("author", "张三", "year", 2025));
// Builder 方式(推荐)
Document doc3 = Document.builder()
.id("custom-id-001")
.text("Spring AI 提供 VectorStore 抽象")
.metadata("source", "docs/vectorstore.md")
.metadata("page", 3)
.build();
核心属性:
| 属性 | 类型 | 说明 |
|---|---|---|
id | String | 唯一标识,默认使用 RandomIdGenerator 生成 |
text | String | 文本内容,与 media 互斥 |
media | Media | 媒体内容(图片/音频等),与 text 互斥 |
metadata | Map<String, Object> | 元数据键值对,值仅支持简单类型(String、Number、Boolean) |
score | Double | 相似度得分,仅在搜索返回时有值 |
注意事项:
text和media必须且只能设置其一,Builder 在build()时进行校验metadata中的值必须是简单类型,嵌套对象或复杂类型可能不被向量数据库支持- 可通过
mutate()方法基于已有 Document 创建 Builder 副本
4. 搜索请求
SearchRequest 封装了相似度搜索的全部参数。
SearchRequest request = SearchRequest.builder()
.query("如何配置 Spring AI 的 VectorStore?")
.topK(10)
.similarityThreshold(0.7)
.filterExpression("author == '张三' && year >= 2024")
.build();
参数说明:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
query | String | "" | 搜索查询文本,将被 EmbeddingModel 转换为向量 |
topK | int | 4 | 返回结果数量 |
similarityThreshold | double | 0.0 | 最低相似度阈值,范围 [0.0, 1.0],0.0 表示不过滤 |
filterExpression | Filter.Expression | null | 元数据过滤条件,支持编程式和文本式两种构建方式 |
5. Filter 表达式 DSL
Spring AI 提供了一套可移植的元数据过滤 DSL,支持编程式、文本式两种构建方式,并由各厂商的 FilterExpressionConverter 转换为原生查询语法。
5.2 编程式 DSL
FilterExpressionBuilder 提供类型安全的流式 API 构建过滤条件。
import static org.springframework.ai.vectorstore.filter.FilterExpressionBuilder.*;
// 等值过滤
Op expr = eq("author", "张三");
// 复合条件
Op expr = and(
eq("author", "张三"),
gte("year", 2024)
);
// 复杂嵌套
Op expr = and(
or(eq("category", "AI"), eq("category", "ML")),
gte("rating", 4.5),
group(or(gt("price", 10), eq("status", "active")))
);
// 逻辑非
Op expr = not(eq("deleted", true));
// 包含/不包含
Op expr = in("tag", "java", "spring", "ai");
Op expr = nin("status", "archived", "deprecated");
Builder 方法速查:
| 方法 | 对应表达式类型 |
|---|---|
eq(key, value) | EQ |
ne(key, value) | NE |
gt(key, value) | GT |
gte(key, value) | GTE |
lt(key, value) | LT |
lte(key, value) | LTE |
in(key, values...) | IN |
nin(key, values...) | NIN |
and(left, right) | AND |
or(left, right) | OR |
not(op) | NOT |
group(op) | 优先级分组 |
所有方法返回 Op record,调用 .build() 获取底层 Filter.Expression。
5.3 文本式 DSL
基于 ANTLR4 语法解析 SQL 风格过滤表达式,适合配置文件中使用。
FilterExpressionTextParser parser = new FilterExpressionTextParser();
Filter.Expression expr = parser.parse(
"author == '张三' && year >= 2024"
);
Filter.Expression expr2 = parser.parse(
"category in ['AI', 'ML'] && (rating >= 4.5 || featured == true)"
);
支持的语法:
| 运算符 | 说明 |
|---|---|
==, != | 等于、不等于 |
>, >=, <, <= | 比较运算 |
IN, NOT IN, NIN | 包含 / 不包含 |
&&, || | 逻辑与、逻辑或 |
! | 逻辑非 |
( ) | 括号分组 |
5.5 在搜索中使用过滤
- 编程式 DSL
- 文本式 DSL
- 内联字符串
// 方式一:编程式 DSL
Filter.Expression filter = and(
eq("category", "documentation"),
gte("year", 2024)
);
List<Document> results = vectorStore.similaritySearch(
SearchRequest.builder()
.query("VectorStore 配置")
.topK(5)
.filterExpression(filter)
.build()
);
// 方式二:文本式 DSL
List<Document> results = vectorStore.similaritySearch(
SearchRequest.builder()
.query("VectorStore 配置")
.topK(5)
.filterExpression(new FilterExpressionTextParser()
.parse("category == 'documentation' && year >= 2024"))
.build()
);
// 方式三:内联字符串(自动解析)
List<Document> results = vectorStore.similaritySearch(
SearchRequest.builder()
.query("VectorStore 配置")
.topK(5)
.filterExpression("category == 'documentation' && year >= 2024")
.build()
);
8. 完整示例
完整示例:VectorStoreDemo.java
@Component
class VectorStoreDemo {
private final VectorStore vectorStore;
public VectorStoreDemo(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
@PostConstruct
void demo() {
// 1. 准备文档
List<Document> documents = List.of(
Document.builder()
.text("Spring AI 为 Java 开发者提供了统一的 AI 模型调用抽象,"
+ "包括 ChatModel、EmbeddingModel、ImageModel 等核心接口。")
.metadata("category", "overview")
.metadata("version", "1.0.0")
.metadata("difficulty", 1)
.build(),
Document.builder()
.text("VectorStore 接口是 Spring AI 向量数据库的统一抽象,"
+ "支持 add、delete、similaritySearch 三类操作,"
+ "并提供可移植的 Filter 表达式 DSL。")
.metadata("category", "vectorstore")
.metadata("version", "1.0.0")
.metadata("difficulty", 3)
.build(),
Document.builder()
.text("ChatClient 提供了链式 API,"
+ "支持流式调用、结构化输出和工具调用等高级特性。")
.metadata("category", "chatclient")
.metadata("version", "1.0.0")
.metadata("difficulty", 2)
.build()
);
// 2. 写入向量数据库(自动嵌入)
vectorStore.add(documents);
// 3. 基础搜索
List<Document> results = vectorStore.similaritySearch(
SearchRequest.builder()
.query("如何使用向量数据库")
.topK(3)
.similarityThreshold(0.5)
.build()
);
for (Document doc : results) {
System.out.printf("[%.4f] %s%n",
doc.getScore(), doc.getText());
}
// 4. 带过滤条件的搜索
List<Document> filtered = vectorStore.similaritySearch(
SearchRequest.builder()
.query("核心接口")
.topK(5)
.filterExpression(
and(
eq("category", "overview"),
lt("difficulty", 3)
)
)
.build()
);
// 5. 按条件删除
vectorStore.delete(
new FilterExpressionTextParser()
.parse("category == 'chatclient'")
);
}
}
VectorStore 内部依赖 EmbeddingModel 完成文档向量化,用户只需注入 VectorStore 即可,无需手动调用 EmbeddingModel。详见 Embedding 章节。