news 2026/4/16 23:07:23

使用 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/4/16 19:51:53

2026年牛客网最新版Java面试题及答案整理

Java学到什么程度可以面试工作&#xff1f; 要达到能够面试Java开发工作的水平&#xff0c;需要掌握以下几个方面的知识和技能&#xff1a; 1. 基础扎实&#xff1a;熟悉Java语法、面向对象编程概念、异常处理、I/O流等基础知识。这是所有Java开发者必备的基础&#xff0c;也…

作者头像 李华
网站建设 2026/4/16 14:40:42

深度测评9个AI论文平台,MBA高效写作必备!

深度测评9个AI论文平台&#xff0c;MBA高效写作必备&#xff01; AI 工具如何重塑论文写作的效率与质量 在当今快速发展的学术环境中&#xff0c;MBA 学生和研究人员正面临着越来越高的写作压力。从选题到开题&#xff0c;从初稿撰写到最终定稿&#xff0c;每一个环节都需要精准…

作者头像 李华
网站建设 2026/4/16 15:37:10

EpiQuik Plant ChIP Kit:高灵敏度与特异性,专为植物样本优化

在生命科学领域&#xff0c;表观遗传学的研究正以前所未有的速度推进。其中&#xff0c;染色质免疫共沉淀&#xff08;ChIP&#xff09;技术作为解析基因组与蛋白质相互作用的核心手段&#xff0c;广泛应用于动植物研究中。尤其是在植物研究中&#xff0c;由于其复杂的基因组结…

作者头像 李华
网站建设 2026/4/16 3:29:07

2026 中专大数据技术专业证书含金量怎么样?

随着毕业季临近&#xff0c;许多中专院校大数据与财务管理专业的学生都在认真思考&#xff1a;在各类专业技能证书中&#xff0c;如何规划出最适合自己的学习路径&#xff1f;这个专业将传统财务管理的严谨逻辑与大数据时代的技术方法相结合&#xff0c;为学生构建了独特的跨领…

作者头像 李华
网站建设 2026/4/16 7:22:15

【SRC】从任意文件上传bypass到SSRF内网突破

【SRC】从任意文件上传bypass到SSRF内网突破 从任意文件上传bypass到SSRF内网突破 下载读取 文件可疑ID遍历/注入 下载接口出现铭感信息的(自己独有的东西)有用户的汇集的地方就很可能存在漏洞 出现数字ID遍历,越权下载其他人文件,GETPOST皆切换尝试,利用IDOR越权,但是有鉴…

作者头像 李华
网站建设 2026/4/15 17:11:38

设计副业复盘工具,录入副业运营数据,分析优势与不足,生成复盘报告,制定优化计划,帮副业从业者持续提升收益。

1. 实际应用场景与痛点分析 场景描述 - 副业从业者&#xff08;如电商卖家、自媒体创作者、自由职业者&#xff09;在运营过程中会积累大量数据&#xff1a; - 收入、支出、流量、转化率、客户反馈等。 - 每次运营后需要总结经验&#xff0c;找出优势与不足。 - 制定下一步优化…

作者头像 李华