VectorStore 与 PGVector
约 629 字大约 2 分钟
布欧-Lewyon
2026-05-15
VectorStore 是向量数据库的统一抽象,PGVector 是 PostgreSQL 的向量存储扩展。
安装 PGVector
# Docker 一键启动 PostgreSQL + pgvector
docker run -d \
--name pgvector \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=vectordb \
-p 5432:5432 \
pgvector/pgvector:0.7.0-pg16添加依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>配置
spring:
datasource:
url: jdbc:postgresql://localhost:5432/vectordb
username: postgres
password: postgres
ai:
vectorstore:
pgvector:
index-type: HNSW # HNSW 或 IVFFlat
distance-type: COSINE_DISTANCE # COSINE, EUCLIDEAN, INNER_PRODUCT
dimension: 1536 # text-embedding-ada-002 的维度
initialize-schema: true # 自动建表VectorStore 接口
@Service
public class VectorStoreService {
private final VectorStore vectorStore;
public VectorStoreService(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
// 添加文档
public void addDocuments(List<Document> documents) {
vectorStore.add(documents);
}
// 语义搜索
public List<Document> search(String query, int topK) {
SearchRequest request = SearchRequest.builder()
.query(query)
.topK(topK)
.similarityThreshold(0.5) // 相似度阈值
.build();
return vectorStore.similaritySearch(request);
}
// 带过滤条件的搜索
public List<Document> searchWithFilter(String query, int topK,
String category) {
SearchRequest request = SearchRequest.builder()
.query(query)
.topK(topK)
.filterExpression("category == '" + category + "'")
.build();
return vectorStore.similaritySearch(request);
}
// 删除文档
public void delete(List<String> documentIds) {
vectorStore.delete(documentIds);
}
}Document 对象
// 构建文档
Document doc = new Document(
"doc-1", // ID
"Spring AI is a framework for building AI applications",
Map.of( // 元数据
"category", "technology",
"author", "Spring Team",
"createdAt", "2026-01-01"
)
);
// 批量构建
List<Document> documents = List.of(
new Document("doc-1", "Content A", Map.of("category", "tech")),
new Document("doc-2", "Content B", Map.of("category", "science"))
);搜索请求详解
SearchRequest request = SearchRequest.builder()
.query("如何集成 Spring AI") // 搜索文本(自动向量化)
.topK(5) // 返回 TOP-5
.similarityThreshold(0.7) // 只返回相似度 >= 0.7 的结果
.filterExpression("category == 'technology'") // 元数据过滤
.build();
List<Document> results = vectorStore.similaritySearch(request);
// 每个 Document 包含相似度分数
results.forEach(doc -> {
System.out.println("ID: " + doc.getId());
System.out.println("Content: " + doc.getContent());
System.out.println("Score: " + doc.getMetadata().get("distance"));
System.out.println("---");
});使用 JDBC 直接查询
@Repository
public class VectorRepository {
private final JdbcTemplate jdbcTemplate;
// 直接执行向量搜索(不通过 VectorStore)
public List<Map<String, Object>> vectorSearch(float[] embedding, int topK) {
// PostgreSQL 的 <=> 操作符表示余弦距离
String arrayLiteral = toPostgresArray(embedding);
String sql = """
SELECT id, content, metadata,
1 - (embedding <=> '%s'::vector) AS similarity
FROM vector_store
ORDER BY embedding <=> '%s'::vector
LIMIT ?
""".formatted(arrayLiteral, arrayLiteral);
return jdbcTemplate.queryForList(sql, topK);
}
private String toPostgresArray(float[] vector) {
return Arrays.stream(vector)
.mapToObj(String::valueOf)
.collect(Collectors.joining(",", "[", "]"));
}
}小结
- VectorStore 是向量数据库的统一抽象,PGVector 是 PostgreSQL 的实现。
- 使用
pgvector/pgvectorDocker 镜像快速搭建。 SearchRequest.query(topK)自动对文本做 Embedding 后搜索。similarityThreshold过滤低相似度结果,filterExpression按元数据过滤。- HNSW 索引适合高精度,IVFFlat 索引适合大数据量。
- PostgreSQL + pgvector 是最成熟的开源向量数据库方案之一。
上一节:Embedding 向量化 下一节:Document 加载与切分
