news 2026/6/8 10:18:06

使用 PostgreSQL + pgvector 实现 RAG 向量存储与语义检索(Java 实战)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 PostgreSQL + pgvector 实现 RAG 向量存储与语义检索(Java 实战)

使用 PostgreSQL + pgvector 实现 RAG 向量存储与语义检索(Java 实战)

在 RAG(Retrieval-Augmented Generation)系统中,向量存储与相似度检索是最核心的一环。
本文将使用PostgreSQL + pgvector,结合Java + 阿里百炼 Embedding 模型,实现一个完整、可运行的向量存储与语义检索示例。

本文不仅关注“能跑”,更重点解释为什么这么设计以及RAG 中最容易踩的坑


一、pgvector 是什么?

pgvector是 PostgreSQL 的一个扩展插件,为 PostgreSQL 提供了专门的vector 类型,用于存储高维向量,并支持:

  • 余弦距离(cosine distance)
  • 欧氏距离(L2)
  • 内积(inner product)
  • 向量索引(ivfflat / hnsw)

这使得 PostgreSQL 可以直接作为向量数据库使用,非常适合中小规模 RAG 场景。


二、安装 PostgreSQL 与 pgvector

安装过程不再赘述。

👉 可参考 CSDN 博主进击的女IT的文章:
https://blog.csdn.net/weixin_63908159/article/details/156075242


三、建表与索引设计(非常重要)

1️⃣ 建表语句

CREATETABLEdocument(id BIGSERIALPRIMARYKEY,contentTEXTNOTNULL,embedding vector(1024),create_timeTIMESTAMPDEFAULTnow());

⚠️注意
vector(1024)必须与 Embedding 模型输出的向量维度一致。如果模型输出是 1536 维,这里必须改成vector(1536),否则插入时会报错:expected xxx dimensions

2️⃣ 向量索引(否则数据一多会非常慢)

CREATEINDEXidx_document_embeddingONdocumentUSINGivfflat(embedding vector_cosine_ops)WITH(lists=100);

查询前建议设置:

SETivfflat.probes=10;

四、Java 实体类设计

pgvector在 Java 中无需特殊类型映射,直接使用String承载即可。

@DatapublicclassDocument{privateLongid;privateStringcontent;/** * pgvector 字段 * 使用 String 承载,例如:[0.12,0.34,...] */privateStringembedding;privateLocalDateTimecreateTime;}

五、Embedding 模型配置(阿里百炼)

配置文件 (application.yml):

alibaba:dashscope:key:sk-xxxurl:https://dashscope.aliyuncs.com/compatible-mode/v1/embeddingsmodel:text-embedding-v4

配置类:

@Configuration@ConfigurationProperties(prefix="alibaba.dashscope")@DatapublicclassAlibabaDashscopeConfig{privateStringkey;privateStringurl;privateStringmodel;}

六、文本向量化服务(EmbeddingService)

功能:文本 → 向量 (List<Float>)

@Service@Slf4jpublicclassEmbeddingService{@AutowiredprivateAlibabaDashscopeConfigconfig;publicList<Float>getEmbedding(Stringtext){if(StrUtil.isBlank(text)){returnList.of();}Map<String,Object>body=Map.of("model",config.getModel(),"input",List.of(text));HttpResponseresponse=HttpRequest.post(config.getUrl()).header("Authorization","Bearer "+config.getKey()).header("Content-Type","application/json").body(JSONUtil.toJsonStr(body)).timeout(30000).execute();JSONObjectjson=JSONUtil.parseObj(response.body());JSONArrayembedding=json.getJSONArray("data").getJSONObject(0).getJSONArray("embedding");returnembedding.toList(Float.class);}}

七、向量存储与相似度查询

Mapper

@MapperpublicinterfaceDocumentMapperextendsBaseMapper<Document>{/** * 向量相似度搜索(余弦距离) */@Select(""" SELECT id, content FROM document ORDER BY embedding <=> #{embedding}::vector LIMIT #{limit} """)List<Document>searchByEmbedding(@Param("embedding")Stringembedding,@Param("limit")intlimit);@Insert(""" INSERT INTO document (content, embedding) VALUES (#{content}, #{embedding}::vector) """)voidinsertDocument(@Param("content")Stringcontent,@Param("embedding")Stringembedding);}

Service

@Service@RequiredArgsConstructorpublicclassDocumentService{privatefinalDocumentMappermapper;privatefinalEmbeddingServiceembeddingService;publicvoidaddDocument(Stringcontent){List<Float>vector=embeddingService.getEmbedding(content);StringpgVector=vector.stream().map(String::valueOf).collect(Collectors.joining(",","[","]"));mapper.insertDocument(content,pgVector);}publicList<Document>search(Stringquery,inttopK){List<Float>vector=embeddingService.getEmbedding(query);if(vector.isEmpty()){returnList.of();}StringpgVector=vector.stream().map(String::valueOf).collect(Collectors.joining(",","[","]"));returnmapper.searchByEmbedding(pgVector,topK);}}

八、Controller 接口

@RestController@RequestMapping("/document")@RequiredArgsConstructorpublicclassDocumentController{privatefinalDocumentServiceservice;@GetMapping("/add")publicvoidadd(@RequestParamStringcontent){service.addDocument(content);}@GetMapping("/search")publicList<Document>search(@RequestParamStringquery,@RequestParam(defaultValue="5")inttopK){returnservice.search(query,topK);}}

九、为什么“最近流行什么”查询不到结果?

这是语义检索中最容易被误解的一点:

向量检索 ≠ 关键词匹配

向量检索判断的是语义是否在同一语义空间

示例:

文本语义中心
Java 是一门流行的后端开发语言编程 / 后端
最近流行什么趋势 / 热点

👉 两者在语义空间中的距离很远,因此检索不到是正常且正确的行为。

正确做法:

  1. Query Rewrite(查询重写)
  2. 补充领域上下文

例如:

最近流行的后端开发语言有哪些?


十、总结

  • pgvector可以让 PostgreSQL 直接作为向量数据库使用。
  • 向量检索本质是语义相似度计算
  • RAG 的效果高度依赖于:
    • 文档内容的表达方式
    • Query 是否足够具体
    • 相似度阈值与 TopK 的设计

📌项目完整源码地址(Gitee)
https://gitee.com/tfxing12138/rag-demo.git

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 22:51:37

39-mini-vue 实现解析 text 功能

实现解析 text 功能 测试 describe("text", ()>{it("simple text",()>{const ast baseParse("some text")expect(ast.children[0]).toStrictEqual({type: NodeTypes.TEXT,content: "some text"})}) })思路&#xff1a; * 如果…

作者头像 李华
网站建设 2026/6/8 8:18:40

利用鲸鱼优化算法WOA对LSTM的学习率等参数进行优化,然后做多特征输入单个因变量输入的拟合预测模型

利用鲸鱼优化算法WOA对LSTM的学习率等参数进行优化&#xff0c;然后做多特征输入单个因变量输入的拟合预测模型&#xff0c;同时利用WOA-LSTM实现对未来数据的预测研究。 程序内注释详细&#xff0c;直接替换数据里可以用。 程序语言为matlab。 最近在时序预测的实战中踩了不少…

作者头像 李华
网站建设 2026/5/31 3:40:06

学霸同款8个AI论文写作软件,本科生轻松搞定论文格式!

学霸同款8个AI论文写作软件&#xff0c;本科生轻松搞定论文格式&#xff01; 论文写作新革命&#xff0c;AI 工具让学术之路更轻松 对于本科生而言&#xff0c;论文写作一直是学习生涯中的一大挑战。从选题到结构搭建&#xff0c;再到内容撰写与格式规范&#xff0c;每一步都可…

作者头像 李华
网站建设 2026/5/31 23:45:07

温湿度控制(有完整资料)

资料查找方式&#xff1a;特纳斯电子&#xff08;电子校园网&#xff09;&#xff1a;搜索下面编号即可编号&#xff1a;CP-51-2021-045设计简介&#xff1a;本设计是基于单片机的温湿度控制系统&#xff0c;主要实现以下功能&#xff1a;可通过LCD1602显示温湿度和阈值&#x…

作者头像 李华
网站建设 2026/6/6 4:28:10

衣柜除湿照明(有完整资料)

资料查找方式&#xff1a; 特纳斯电子&#xff08;电子校园网&#xff09;&#xff1a;搜索下面编号即可 编号&#xff1a; CP-51-2021-049 设计简介&#xff1a; 本设计是基于单片机的衣柜除湿照明系统&#xff0c;主要实现以下功能&#xff1a; 可通过LCD1602显示温湿度&…

作者头像 李华
网站建设 2026/6/3 19:37:57

学网络安全对学历有什么要求?

想入行网络安全&#xff0c;学历要求是很多新手的核心顾虑&#xff0c;担心学历偏低会被行业拒之门外。其实网络安全是重实战&#xff0c;轻学历的赛道&#xff0c;学历并非硬性门槛&#xff0c;那么学网络安全对学历有什么要求?请看下文。 学网络安全对学历有什么要求? 对于…

作者头像 李华