摘要生成中...
AI 摘要
Hunyuan-lite

向量数据库是一种专门类型的数据库,它的查询和传统的关系型数据库有所不同。向量数据库执行的是相似性搜索而非精确匹配,当我们给定一个向量作为查询时,向量数据库会返回与查询向量「相似」的向量。

PGvector 是 PostgreSQL 的一个开源扩展,它能够存储和搜索由嵌入向量。

本文将介绍使用 Spring AI 框架开发智能体应用时,在 RAG 步骤中的向量数据库搭建和使用环节的操作过程。

使用 PostgreSQL 的 PGVector 构建向量存储

Linux 服务器中手动安装 PostgreSQL 以及插件

PostgreSQL 的安装

本文使用的云服务器环境信息

Alibaba Cloud Linux 3(基于 Anolis OS 8 打造,兼容 CentOS 8 / RHEL 8 生态),x86_64.

安装 PostgreSQL 18:

1
2
3
4
5
6
7
8
9
10
# 安装 postgresql18-server 
yum install -y postgresql18-server
# 检查 PostgreSQL 版本
psql --version
# 初始化数据库(首次安装必做)
/usr/pgsql-18/bin/postgresql-18-setup initdb
# 启动服务并设置开机自启
systemctl enable --now postgresql-18
# 检查服务状态(显示 active(running) 即为成功)
systemctl status postgresql-18

重启 PostgreSQL:

1
systemctl restart postgresql-18

将其添加到环境变量:

1
2
3
4
5
6
7
8
9
10
11
12
# 查看 psql 所在路径
which psql
# 正常输出:/usr/pgsql-18/bin/psql

# 编辑系统全局环境变量文件
vi /etc/profile

# 在文件末尾添加以下内容
export PATH=$PATH:/usr/pgsql-18/bin

# 保存退出
source /etc/profile

验证环境变量是否生效:

1
2
3
4
5
psql --version
pg_ctl --version
# 输出版本信息即为配置成功,示例:
# psql (PostgreSQL) 18.2
# pg_ctl (PostgreSQL) 18.2

简要介绍 PostgreSQL 命令行进入和退出的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
su postgres # 退出方式为 exit

# 1. 连接 PostgreSQL 数据库(默认连接 postgres 库)
psql

# 2. 退出数据库命令行
\q

# 3. 查看数据库列表
psql -c "\l"

# 4. 启动/停止 PostgreSQL 服务(也可 root 执行 systemctl)
pg_ctl start -D /var/lib/pgsql/18/data/
pg_ctl stop -D /var/lib/pgsql/18/data/

PGVector 插件的安装与验证

安装 PGVector 插件:

1
sudo yum install pgvector_18 # 这里我选择 yum 方式安装

进入 PostgreSQL 交互命令行执行测试:

1
2
3
4
5
6
7
8
9
10
11
-- 创建并切换数据库
create database ai_blog_vec;
\c ai_blog_vec
-- 启用该扩展程序(在您希望使用该扩展程序的每个数据库中执行此操作一次)
CREATE EXTENSION vector;
-- 创建一个具有 3 个维度的向量列
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
-- 插入向量
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
-- Get the nearest neighbors by L2 distance
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;

为远程连接数据库做准备

安装完成后,PostgreSQL 的配置文件在目录 /var/lib/pgsql/18/data 下。一般比较常见的是修改 postgresql.confpg_hba.conf ,可以修改监听地址允许远程连接数据库、修改默认端口号、以及 IP 黑白名单限制等。

postgresql.conf 中允许远程连接:

image.png

设置 postgres 的密码:

1
2
# 设置 postgres 用户密码(替换为你的密码)
ALTER USER postgres WITH PASSWORD '你的强密码';

重启 PostgreSQL:

1
2
3
4
5
6
7
8
# 切换回 root 用户(或直接用 postgres 用户执行)
exit

# 重启服务
systemctl restart postgresql-18

# 检查服务状态(确保启动成功)
systemctl status postgresql-18

注意开放阿里云 ECS 安全组即可。

使用阿里云 Serverless 数据库产品进行构建

官网 中购买相应的 Serverless 产品:

image.png

选择基础配置:

image.png

进入云数据库 RDB 控制台,点击进入相应实例并创建账号:

image.png

然后创建数据库:

image.png

进入插件管理安装相应插件:

image.png

在数据库连接中开通外网地址:

image.png

省钱小贴士

阿里云 RDB 请开启「自动启停」,这样可以减缓烧钱速度。开启后,在低频率的使用场景下,预估费用为 30 元/月左右。

使用数据库连接工具连接 PostgreSQL

我们可以根据外网地址、端口号、用户名、密码、数据库这些信息,使用数据库连接工具即可进行连接。比如使用 IDEA 的数据库连接工具:

image.png

Navicat 连接注意事项

Navicat 连接 PostgreSQL 18 需要将其升级到 Navicat 17。

Spring AI 构建向量数据库

完成好向量数据库的构建后,接下来,我们参照 Spring AI 的 官方文档 整合 PGVector。

在此之前,确保远程 PostgreSQL 向量数据库已经新开有数据库,比如本文的 ai_blog_vec,并且启动了 PGVector 拓展。如果后续报漏装拓展错误可以自行补装(详见后续章节)。数据库里暂时不需要建立表格。

Spring AI 项目中导入依赖:

1
2
3
4
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
</dependency>

在配置文件中做好以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
spring:
datasource:
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: postgres
ai:
vectorstore:
pgvector:
index-type: HNSW
distance-type: COSINE_DISTANCE
# dimensions: 1536 # 维度数据请确认好再调整
max-document-batch-size: 10000 # Optional: Maximum number of documents per batch

Java 中可以编写一段简单的测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Autowired 
VectorStore vectorStore;

// ...

List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
new Document("The World is Big and Salvation Lurks Around the Corner"),
new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));

// Add the documents to PGVector
vectorStore.add(documents);

// Retrieve documents similar to a query
List<Document> results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());

因为向量的制作是需要使用 Embedding 模型制作向量的,如果你的项目中引入了许多同名的 EmbeddingModel 的 Bean,用上面的方式可能会报错。这时我们可以换另外一种方式初始化 VectorStore

首先引入依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store</artifactId>
</dependency>

然后编写配置类自己构造 VectorStore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Configuration
public class PgVectorVectorStoreConfig {

@Bean
public VectorStore pgVectorVectorStore(JdbcTemplate jdbcTemplate, EmbeddingModel dashscopeEmbeddingModel) {
VectorStore vectorStore = PgVectorStore.builder(jdbcTemplate, dashscopeEmbeddingModel)
.dimensions(1536) // 不要盲目设置
.distanceType(COSINE_DISTANCE) // Optional: defaults to COSINE_DISTANCE
.indexType(HNSW) // Optional: defaults to HNSW
.initializeSchema(true) // Optional: defaults to false
.schemaName("public") // Optional: defaults to "public"
.vectorTableName("vector_store") // Optional: defaults to "vector_store"
.maxDocumentBatchSize(10000) // Optional: defaults to 10000
.build();
return vectorStore;
}
}

然后我们就可以使用 pgVectorVectorStore 这个 Bean 了。

错误解决

向量维度数设置错误

如果在后续的运行中,出现向量维度数指定错误的情况时,我们需要清空表格,调整好表的结构在执行一次向量数据库的构建。

数据库拓展缺失错误

如果本地运行出现以下错误,说明服务器中还缺少一个拓展:

相关错误信息

StatementCallback; uncategorized SQLException for SQL [CREATE EXTENSION IF NOT EXISTS hstore]; SQL state [0A000]; error code [0]; ERROR: extension “hstore” is not available

建议:The extension must first be installed on the system where PostgreSQL is running.

解决方法:

1
2
# 安装 postgresql18-contrib 包(包含 hstore、pg_trgm 等扩展)
yum install -y postgresql18-contrib
1
2
3
4
5
6
7
8
9
10
11
# 切换到 postgres 用户
su - postgres

# 连接到你的目标数据库
psql -d ai_blog_vec

# 执行启用 hstore 扩展的命令
CREATE EXTENSION IF NOT EXISTS hstore;

# 验证是否启用成功(输出 hstore 即为成功)
\dx hstore

成功示例:

image.png

本文参考