MySQL 向量存储与语义检索
约 468 字大约 2 分钟
布欧-Lewyon
2026-06-08
首页 › Agent Spring Boot › RAG 检索增强
存储方案
向量以 JSON 字符串 存在 MySQL article.embedding(LONGTEXT),不用 pgvector / Milvus。适合文章量级在数百以内的 Demo;上万篇需换专用向量库。
检索入口
ArticleService.search(String queryText):
return embeddingService.embed(queryText)
.flatMap(vector -> {
if (embeddingService.isValid(vector)) {
return doVectorSearch(vector);
}
return doKeywordSearch(queryText);
});自动降级:Embedding API 不可用时走关键词 BM25 风格检索。
向量检索 doVectorSearch
List<Article> articles = articleRepository.findAllWithEmbedding();
// 对每篇 jsonToVector → cosineSimilarity(query, doc)
// 过滤 similarity >= rag.search.similarity-threshold
// 取 top rag.search.top-k(默认 3)余弦相似度在 Java 内存计算:
double cosineSimilarity(float[] a, float[] b) {
double dot = 0, normA = 0, normB = 0;
for (int i = 0; i < a.length; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}关键词兜底 doKeywordSearch
Embedding 失败时:
- 对 query 和文章做分词 / 2-gram
- BM25 风格打分排序
- 同样返回
List<Article>结构,上层无感
配置
rag:
search:
top-k: 3
similarity-threshold: 0.5
spring:
datasource:
url: jdbc:mysql://localhost:3306/agent_rag
jpa:
hibernate:
ddl-auto: validate验证检索
curl "http://localhost:8080/api/articles/search?query=Spring%20Boot%20事务"
# 返回带 similarity 字段的文章列表对照 sql/data.sql 样例数据做 walkthrough,见项目 docs/rag/RAG-RETRIEVAL-WALKTHROUGH.md。
架构对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| MySQL JSON + Java 算相似度 | 零额外组件、易调试 | 全表扫描,规模差 |
| PGVector | SQL 内向量索引 | 需 PG 扩展 |
| Milvus / Redis Stack | 大规模专用 | 运维成本高 |
学习点
- 检索 = embed(query) + 相似度排序 + threshold + topK。
- 降级路径保证 API 挂掉时仍有关键词结果。
- Demo 与生产的分界线在数据量和延迟。
小结
ArticleService.search统一向量/关键词双策略。- 配置
top-k和similarity-threshold调召回。 - 规模上来后把
findAllWithEmbedding换成 VectorStore。
