1、在pom.xml 引入依赖
xml
<!-- 自动整合 PGVector 向量存储 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
<version>1.0.0-M7</version>
</dependency>
2、application.yml 加入pgvector配置
yaml
spring:
ai:
dashscope:
# 需要替换为你自己的 key
api-key: 你的API-Key
embedding:
options:
model: qwen3.7-text-embedding
dimensions: 1024
######################################################
########### postgresql 向量数据库配置 #############
######################################################
vectorstore:
pgvector:
initialize-schema: true # 会自定初始化向量数据表 vector_store
index-type: HNSW # 量索引的类型为 HNSW(分层可导航小世界图)。
dimensions: 1024 # 存储的向量维度为 1024。
distance-type: COSINE_DISTANCE # 相似度度量方式为"余弦距离
max-document-batch-size: 10000 # Optional: Maximum number of documents per batch
id-type: uuid
table-name: vector_store # 向量数据表表名
schema-name: public
datasource:
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: 123456
项目启动时会自动创建向量数据表,表名为:vector_store
3、测试向表中vector_store 插入数据
service
java
/**
* 向量数据库表 vector_store 业务操作接口类
*/
public interface IVectorStoreService {
/**
* 简单示例,往向量数据库中插入字符串类型的数据
* @param knowledge
* @return
*/
String addSimple(String knowledge);
/**
* 从向量数据库中筛选文档
* @param content
* @return
*/
List<Document> similaritySearch(String content);
}
serviceImpl
java
@Service
@Slf4j
public class VectorStoreServiceImpl implements IVectorStoreService {
@Autowired
private PgVectorStore pgVectorStore;
@Autowired
@Qualifier("openAiChatModel")
private ChatModel chatModel;
@Override
public String addSimple(String knowledge) {
Document document = new Document(knowledge);
pgVectorStore.add(List.of(document));
return "添加知识库成功";
}
/**
* 根据内容相识度查询
* @param content
*/
public List<Document> similaritySearch(String content){
Query query = new Query(content);
ChatClient.Builder chatClientBuilder = ChatClient.builder(chatModel);
// 构建查询重写转换器
RewriteQueryTransformer queryTransformer = RewriteQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.build();
// 构建翻译成中文转换器
/* QueryTransformer queryTransformer = TranslationQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.targetLanguage("Chinese")
.build();*/
// 重写
Query transform = queryTransformer.transform(query);
SearchRequest searchRequest = SearchRequest.builder()
.query(transform.text()) //搜索的查询文本,重写后的查询
.topK(5) // 返回的最大结果数
.similarityThreshold(0.5) // 相似度阈值分数,用于筛选搜索结果。只有相似度得分大于或等于该"阈值"的文档才会被返回。请注意,这是一个在客户端而非服务端执行的后处理步骤。阈值设为 0.0 表示接受任意相似度,或禁用相似度阈值过滤;阈值设为 1.0 则表示要求完全匹配。
//.filterExpression("title in ['如何提升自身魅力吸引潜在伴侣?']") //基于文档元数据的过滤表达式
.build();
// Retrieve documents similar to a query
List<Document> results = pgVectorStore.similaritySearch(searchRequest);
log.info("匹配到的知识库内容:{}",results.toArray());
return results;
}
}
测试方法,这里就直接写controller了,在页面上测试
java
/**
* 向量数据库接口
*/
@RestController
@RequestMapping("/vectorStore")
public class VectorStoreController {
@Autowired
private IVectorStoreService vectorStoreService;
/**
* 新增数据
* 向vector_store插入数据
* @param knowledge 字符串类型的知识
*/
@PostMapping("/add")
public String addSimple(String knowledge){
return vectorStoreService.addSimple(knowledge);
}
/**
* 查询-直接接口查询
* @param content
* @return
*/
@GetMapping("/query")
public List<Document> similaritySearch( String content){
return vectorStoreService.similaritySearch(content);
}
}
- 先测试下插入数据

查看数据库,发现插入成功,embedding字段即为向量数组,metadata元信息为空,是因为我们暂时还没有设置。

继续多插入几条

测试下检索功能,发现只匹配到一条,分数为0.66


4、哪为什么会检索到这条呢?
- 先将用户输入的信息向量化

- 再通过jdbc在数据库中匹配

5、总结
在这里其实我们对RAG中的向量化,检索有初步的了解了。在这篇文章中主要是将向量数据库pgvector集成到项目中,并用简单的插入表,检索表了解了向量化。在检索文档前,会将用户输入的文本转化为向量表示,再从表中检索内容。【下图红色圈出部分】
附上一张RAG的架构图:

