跳到主要内容
Spring AI 集成 PGvector:向量存储与相似性搜索实战 | 极客日志
Java AI java 算法
Spring AI 集成 PGvector:向量存储与相似性搜索实战 综述由AI生成 PGvector 作为 PostgreSQL 的向量扩展,结合 Spring AI 框架,为 RAG 应用提供了高效的向量存储与检索方案。文章涵盖了从环境搭建、依赖配置到实际代码实现的完整流程,重点演示了文档存储、相似度搜索及元数据过滤等核心操作。通过对比 HNSW 与 IVFFlat 索引特性,并给出性能优化与安全实践建议,帮助开发者快速构建基于向量数据库的智能应用系统。
雾岛听风 发布于 2026/3/15 更新于 2026/4/27 2 浏览Spring AI 集成 PGvector:向量存储与相似性搜索实战
一、PGvector 概述与核心价值
1.1 什么是 PGvector
PGvector 是 PostgreSQL 的开源扩展,专为向量相似性搜索设计。它允许开发者直接在 PostgreSQL 中存储和搜索机器学习生成的嵌入(embeddings),支持精确和近似最近邻搜索。
选择 PGvector 的理由很直接:
无缝集成 :作为原生扩展,与现有 Postgres 生态协作无感。
ACID 合规 :保持数据库的事务完整性,数据一致性有保障。
功能丰富 :支持多种距离度量和索引类型,适应不同场景。
高性能 :针对大规模向量搜索进行了专门优化。
易用性 :提供标准 SQL 接口,无需学习新的查询语言。
1.2 关键特性一览
特性 描述 优势 向量存储 支持 vector, halfvec, bit, sparsevec 等类型 适应不同精度和内存需求 距离度量 L2、内积、余弦距离、L1、汉明距离等 适用于不同场景的相似性度量 索引类型 HNSW、IVFFlat 平衡查询速度和召回率 元数据过滤 基于 JSON 的元数据过滤 精确控制检索结果 混合搜索 结合向量搜索和文本搜索 提高检索相关性
1.3 与 Spring AI 的集成
Spring AI 通过 spring-ai-starter-vector-store-pgvector 提供了开箱即用的支持,让开发者能轻松将向量数据库集成到 RAG(检索增强生成)应用中。
<dependency >
<groupId > org.springframework.ai</groupId >
<artifactId > spring-ai-starter-vector-store-pgvector</artifactId >
</dependency >
二、环境准备与配置
2.1 前提条件
在使用 PGvector 之前,需要确保 PostgreSQL 实例已启用必要的扩展。执行以下 SQL 命令初始化环境:
EXTENSION IF vector;
EXTENSION IF hstore;
EXTENSION IF "uuid-ossp";
CREATE
NOT
EXISTS
CREATE
NOT
EXISTS
CREATE
NOT
EXISTS
2.2 创建向量存储表 虽然 Spring AI 支持自动建表,但了解底层结构很有必要。推荐在应用启动时由框架自动创建,手动创建示例如下:
CREATE TABLE IF NOT EXISTS vector_store (
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY ,
content text,
metadata json,
embedding vector(1536 )
);
CREATE INDEX IF NOT EXISTS vector_index
ON vector_store USING hnsw (embedding vector_cosine_ops);
💡 注意 :如果使用不同的嵌入维度,请将 1536 替换为实际值。PGvector 对 HNSW 索引最多支持 2000 个维度。
三、Spring AI 集成实践
3.1 依赖配置 在 Maven 项目中添加 PGvector 向量存储依赖(如未使用 starter):
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-jdbc</artifactId >
</dependency >
<dependency >
<groupId > org.postgresql</groupId >
<artifactId > postgresql</artifactId >
<scope > runtime</scope >
</dependency >
<dependency >
<groupId > org.springframework.ai</groupId >
<artifactId > spring-ai-pgvector-store</artifactId >
</dependency >
3.2 自动配置 Spring AI 提供了自动配置功能,通过 application.yml 即可快速连接:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: postgres
ai:
vectorstore:
pgvector:
index-type: HNSW
distance-type: COSINE_DISTANCE
dimensions: 1536
max-document-batch-size: 10000
initialize-schema: true
initialize-schema: true:应用启动时自动创建所需的数据库表。
dimensions:嵌入维度,如果未指定将从 EmbeddingModel 获取。
index-type:索引类型(HNSW、IVFFlat、NONE)。
distance-type:距离类型(COSINE_DISTANCE、EUCLIDEAN_DISTANCE 等)。
3.3 手动配置(高级用法) 如果不使用 Spring Boot 自动配置,可以手动构建 PgVectorStore Bean:
@Configuration
public class PgVectorConfig {
@Bean
public VectorStore vectorStore (JdbcTemplate jdbcTemplate, EmbeddingModel embeddingModel) {
return PgVectorStore.builder(jdbcTemplate, embeddingModel)
.dimensions(1536 )
.distanceType(COSINE_DISTANCE)
.indexType(HNSW)
.initializeSchema(true )
.schemaName("public" )
.vectorTableName("vector_store" )
.maxDocumentBatchSize(10000 )
.build();
}
}
四、核心操作实战
4.1 存储文档 首先注入 VectorStore 组件,然后准备文档对象进行存储。这里我们模拟一批包含元数据的文档。
@Resource
@Qualifier("pgVectorStore")
private VectorStore vectorStore;
public void storeDocuments () {
List<Document> documents = List.of(
new Document ("Spring AI rocks!!" , Map.of("author" , "john" , "article_type" , "blog" )),
new Document ("The World is Big and Salvation Lurks Around the Corner" , Map.of("author" , "jill" , "category" , "philosophy" )),
new Document ("Artificial Intelligence is transforming the tech industry." , Map.of("author" , "bob" , "category" , "ai" ))
);
System.out.println("开始存储文档..." );
vectorStore.add(documents);
System.out.println("文档存储完成!" );
List<Document> results = vectorStore.similaritySearch(
SearchRequest.builder().query("Spring" ).topK(5 ).build()
);
results.forEach(doc -> {
System.out.println("内容:" + doc.getText());
System.out.println("元数据:" + doc.getMetadata());
});
}
4.2 基本相似性搜索 执行相似度搜索时,可以设置阈值来过滤低相关性的结果。
public List<Document> basicSimilaritySearch () {
SearchRequest searchRequest = SearchRequest.builder()
.query("Spring" )
.topK(3 )
.similarityThreshold(0.5 )
.build();
List<Document> results = vectorStore.similaritySearch(searchRequest);
results.forEach(doc -> {
System.out.println("内容:" + doc.getText());
System.out.println("相似度:" + doc.getMetadata().get("distance" ));
});
return results;
}
4.3 元数据过滤 除了向量相似度,元数据过滤能进一步缩小范围。Spring AI 支持两种过滤方式:文本表达式和编程式 DSL。
public List<Document> searchWithTextFilter () {
SearchRequest searchRequest = SearchRequest.builder()
.query("technology" )
.topK(5 )
.filterExpression("author in ['john', 'jill'] && article_type == 'blog'" )
.build();
return vectorStore.similaritySearch(searchRequest);
}
public List<Document> searchWithProgrammaticFilter () {
FilterExpressionBuilder b = new FilterExpressionBuilder ();
List<Document> results = vectorStore.similaritySearch(
SearchRequest.builder()
.query("technology" )
.topK(5 )
.filterExpression(b.and(
b.in("author" , "john" , "jill" ),
b.eq("article_type" , "blog" )
).build())
.build()
);
return results;
}
4.4 删除文档 根据元数据查找并删除特定文档。注意不同实现可能略有差异,通常需要先查询 ID 再删除。
public void deleteDocumentsByMetadata () {
FilterExpressionBuilder builder = new FilterExpressionBuilder ();
Filter.Expression filter = builder.eq("author" , "john" ).build();
List<Document> docsToDelete = vectorStore.similaritySearch(
SearchRequest.builder().query("" ).topK(100 ).filterExpression(filter).build()
);
if (!docsToDelete.isEmpty()) {
List<String> ids = docsToDelete.stream()
.map(Document::getId)
.filter(Objects::nonNull)
.toList();
System.out.println("找到 " + ids.size() + " 个要删除的文档" );
vectorStore.delete(ids);
}
}
五、性能优化与最佳实践
5.1 索引类型对比 索引类型 构建时间 查询性能 内存使用 适用场景 HNSW 较慢 优秀 较高 高性能要求,数据量大 IVFFlat 快 一般 较低 数据量小,内存有限 NONE 无 一般 低 测试环境,小数据量
建议: 对于 100K+ 向量,首选 HNSW;10K-100K 可选 IVFFlat;小于 10K 可考虑 NONE。
5.2 参数调优
CREATE INDEX ON vector_store USING hnsw (embedding vector_cosine_ops)
WITH (m = 16 , ef_construction = 64 );
m:每层最大连接数(默认 16)。
ef_construction:构建时的动态候选列表大小(默认 64)。高召回率可提高此值。
SET hnsw.ef_search = 100 ;
ef_search:查询时的动态候选列表大小(默认 40)。值越大召回率越高,但速度越慢。
5.3 安全与 RAG 集成 权限管理: 为应用用户创建最小权限角色,避免直接暴露 root 权限。
CREATE ROLE app_user;
GRANT CONNECT ON DATABASE postgres TO app_user;
GRANT USAGE ON SCHEMA public TO app_user;
GRANT SELECT , INSERT , UPDATE , DELETE ON TABLE vector_store TO app_user;
RAG 流程集成: 利用 Spring AI 的 Advisor 机制,可以轻松将向量检索嵌入到问答流程中。
@Bean
public Advisor questionAnswerAdvisor (VectorStore vectorStore) {
return QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder()
.similarityThreshold(0.7 )
.topK(5 )
.build())
.build();
}
六、常见问题排查
6.1 查询性能差
原因 :未使用合适索引或参数未优化。
解决 :确认已创建 HNSW 或 IVFFlat 索引,并检查 hnsw.ef_search 设置。
6.2 向量维度不匹配
原因 :数据库表定义维度与 EmbeddingModel 不一致。
解决 :在配置中显式指定 dimensions,或修改表结构确保一致。
6.3 元数据过滤无效
原因 :过滤表达式格式错误或元数据格式不一致。
解决 :检查日志中的 SQL 语句,确保元数据 Key 名称拼写正确。
七、总结 PGvector 结合 Spring AI 为 Java 生态提供了强大的向量检索能力。通过正确的配置维度、距离类型和索引策略,可以实现高效的 RAG 应用。在实际开发中,注意元数据的安全过滤以及生产环境的性能调优,能让系统更加稳健可靠。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online