Docker 安装与配置 pgvector
1. Docker 安装 PostgreSQL 并启用 pgvector 扩展
####方法一:使用 Docker Compose(推荐)
创建一个docker-compose.yml文件,内容如下:
version: '3.8' services: postgres: image: pgvector/pgvector:pg17 # 使用官方pgvector镜像,指定PostgreSQL版本 container_name: pgvector_db environment: POSTGRES_USER: admin POSTGRES_PASSWORD: your_password POSTGRES_DB: vector_db ports: "5432:5432" volumes: postgres_data:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql # 初始化脚本 restart: unless-stopped volumes: postgres_data:创建初始化脚本init.sql,用于自动创建扩展:
-- 启用pgvector扩展 CREATE EXTENSION IF NOT EXISTS vector;启动服务:
docker-compose up -d方法二:使用 Docker 命令直接运行
docker run -d \ --name pgvector_db \ -e POSTGRES_USER=admin \ -e POSTGRES_PASSWORD=your_password \ -e POSTGRES_DB=vector_db \ -p 5432:5432 \ -v postgres_data:/var/lib/postgresql/data \ pgvector/pgvector:pg17进入容器并手动启用扩展:
docker exec -it pgvector_db psql -U admin -d vector_db -- 在psql命令行中执行 CREATE EXTENSION vector;方法三:基于官方 PostgreSQL 镜像安装扩展
如果需要使用特定版本的 PostgreSQL,可以使用以下 Dockerfile:
FROM postgres:17-bookworm RUN apt-get update && apt-get install -y postgresql-17-pgvector然后构建并运行容器 。
2. 验证安装
连接数据库后执行以下命令验证:
-- 检查扩展是否已安装 SELECT * FROM pg_extension WHERE extname = 'vector'; -- 查看pgvector版本 SELECT extversion FROM pg_extension WHERE extname = 'vector';pgvector 语法详解与使用示例
1. 向量数据类型
pgvector 引入了vector类型,用于存储高维向量。
| 数据类型 | 描述 | 示例 |
|---|---|---|
vector(n) | n维向量,n为维度数 | vector(128) |
vector | 动态维度向量 | vector |
-- 创建包含向量列的表 CREATE TABLE items ( id BIGSERIAL PRIMARY KEY, embedding VECTOR(3), -- 3维向量 text TEXT ); -- 插入向量数据 INSERT INTO items (embedding, text) VALUES ('[1,2,3]', 'item1'), ('[4,5,6]', 'item2'), ('[7,8,9]', 'item3');2. 向量操作符与距离函数
pgvector 支持多种距离计算方式:
| 操作符 | 函数 | 描述 | 距离公式 |
|---|---|---|---|
<-> | l2_distance() | 欧几里得距离(L2) | √Σ(xᵢ - yᵢ)² |
<#> | inner_product() | 内积(负值) | -Σ(xᵢ × yᵢ) |
<=> | cosine_distance() | 余弦距离 | 1 - (Σ(xᵢ × yᵢ) / (√Σxᵢ² × √Σyᵢ²)) |
-- 使用操作符计算距离 SELECT text, embedding <-> '[1,2,3]' AS l2_distance, embedding <=> '[1,2,3]' AS cosine_distanceFROM itemsORDER BY embedding <-> '[1,2,3]' LIMIT 5; -- 使用函数计算距离 SELECT text, l2_distance(embedding, '[1,2,3]') AS l2_dist, cosine_distance(embedding, '[1,2,3]') AS cos_dist FROM items;3. 相似性搜索
最近邻搜索(K-NN)
-- 查找与给定向量最相似的5个项 SELECT id, text, embedding <-> '[3,1,2]' AS distance FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5; -- 带过滤条件的相似性搜索 SELECT id, text, embedding <=> '[0.1,0.2,0.3]' AS similarity FROM items WHERE text LIKE '%重要%' ORDER BY embedding <=> '[0.1,0.2,0.3]' LIMIT 10;距离阈值过滤
-- 查找距离小于指定阈值的所有项 SELECT id, text, embedding <-> '[1,1,1]' AS distance FROM items WHERE embedding <-> '[1,1,1]' < 5.0 ORDER BY distance;4. 向量索引
为了提高相似性搜索性能,pgvector 支持两种索引类型:
IVFFlat 索引(适合中等规模数据集)
-- 创建IVFFlat索引 CREATE INDEX ON itemsUSING ivfflat (embedding vector_l2_ops) WITH (lists = 100); -- 参数说明: -- lists: 聚类中心数量,通常设置为 sqrt(行数) --适用于:L2距离、内积、余弦距离HNSW 索引(适合大规模数据集,查询性能更好)
-- 创建HNSW索引 CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 16, ef_construction = 64); -- 参数说明: -- m: 每个节点的最大连接数(默认16) -- ef_construction: 构建时的动态候选列表大小(默认64) -- ef_search: 查询时的动态候选列表大小(默认40,创建索引时不设置)索引使用示例
-- 创建不同距离度量的索引 -- 1. L2距离索引 CREATE INDEX items_embedding_l2_idx ON items USING hnsw (embedding vector_l2_ops); -- 2. 内积索引 CREATE INDEX items_embedding_ip_idx ON items USING hnsw (embedding vector_ip_ops); -- 3. 余弦距离索引 CREATE INDEX items_embedding_cosine_idx ON items USING hnsw (embedding vector_cosine_ops); -- 设置索引参数优化查询 SET hnsw.ef_search = 100; -- 提高召回率,但可能降低查询速度 -- 使用索引进行搜索 EXPLAIN ANALYZE SELECT id, text, embedding <-> '[1,2,3]' AS distance FROM items ORDER BY embedding <-> '[1,2,3]' LIMIT 10;5. 向量运算与函数
向量算术运算
-- 向量加减法 SELECT '[1,2,3]'::vector + '[4,5,6]'::vector AS addition; -- 结果: [5,7,9] SELECT '[5,7,9]'::vector - '[1,2,3]'::vector AS subtraction; -- 结果: [4,5,6] -- 向量标量乘法 SELECT '[1,2,3]'::vector * 2 AS scalar_multiply; -- 结果: [2,4,6] -- 向量归一化(单位向量) SELECT l2_normalize('[1,2,3]'::vector) AS normalized;向量聚合函数
-- 计算向量平均值 SELECT avg(embedding) AS avg_embedding FROM items; -- 向量求和 SELECT sum(embedding) AS sum_embedding FROM items;6. 完整使用示例
场景:商品推荐系统
-- 1. 创建商品表 CREATE TABLE products ( id SERIAL PRIMARY KEY, name VARCHAR(255), description TEXT, embedding VECTOR(384), -- 使用sentence-transformers生成的384维向量 category VARCHAR(100), price DECIMAL(10,2) ); -- 2. 插入示例数据 INSERT INTO products (name, description, embedding, category, price) VALUES ('智能手机', '高性能智能手机', '[0.1,0.2,0.3,...]'::vector(384), '电子产品', 2999.00), ('平板电脑', '轻薄便携平板', '[0.2,0.3,0.4,...]'::vector(384), '电子产品', 1999.00), ('运动鞋', '专业跑步鞋', '[0.5,0.6,0.7,...]'::vector(384), '运动装备', 599.00); -- 3. 创建HNSW索引CREATE INDEX products_embedding_idx ON products USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64); -- 4. 基于用户历史查找相似商品 WITH user_history AS ( SELECT avg(embedding) AS user_vector FROM products WHERE id IN (1, 2) -- 用户购买过的商品ID ) SELECT p.id, p.name, p.category, p.price, 1 - (p.embedding <=> uh.user_vector) AS similarity_score FROM products p, user_history uh WHERE p.id NOT IN (1, 2) -- 排除已购买商品 ORDER BY p.embedding <=> uh.user_vector LIMIT 10; -- 5. 混合查询:相似性 + 价格过滤 SELECT id, name, price, embedding <=> '[0.15,0.25,0.35,...]' AS distance FROM products WHERE price BETWEEN 1000 AND 3000 AND category = '电子产品' ORDER BY distance LIMIT 5;场景:文本语义搜索
-- 1. 创建文档表 CREATE TABLE documents ( id BIGSERIAL PRIMARY KEY, title TEXT, content TEXT, embedding VECTOR(768), -- BERT等模型生成的768维向量 created_at TIMESTAMP DEFAULT NOW() ); -- 2. 语义搜索函数 CREATE OR REPLACE FUNCTION semantic_search( query_vector VECTOR(768), similarity_threshold FLOAT DEFAULT 0.7, max_results INT DEFAULT 10 ) RETURNS TABLE ( doc_id BIGINT, title TEXT, similarity FLOAT, snippet TEXT ) AS $$ BEGIN RETURN QUERY SELECT d.id, d.title, 1 - (d.embedding <=> query_vector) AS similarity, substring(d.content from 1 for 200) AS snippet FROM documents d WHERE 1 - (d.embedding <=> query_vector) > similarity_threshold ORDER BY d.embedding <=> query_vector LIMIT max_results; END; $$ LANGUAGE plpgsql; -- 3. 使用函数进行搜索 SELECT * FROM semantic_search('[0.1,0.2,0.3,...]'::vector(768), 0.8, 5);7. 性能优化建议
索引选择策略:
数据量 < 100万:考虑 IVFFlat
数据量 > 100万:使用 HNSW
内存充足时:HNSW 通常性能更好索引参数调优:
-- 构建时优化召回率 CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 32, ef_construction = 128); -- 查询时临时调整 SET hnsw.ef_search = 200; -- 提高搜索精度 SET enable_seqscan = off; -- 强制使用索引- 批量插入优化:
-- 禁用索引加速批量插入 DROP INDEX items_embedding_idx; -- 批量插入数据 INSERT INTO items (embedding, text) VALUES (...), (...), ...; -- 重新创建索引 CREATE INDEX items_embedding_idx ON items USING hnsw (embedding vector_l2_ops);- 查询性能分析:
-- 使用EXPLAIN ANALYZE分析查询计划 EXPLAIN ANALYZE SELECT id, embedding <-> '[1,2,3]' AS dist FROM items ORDER BY dist LIMIT 10;8. 注意事项
- 维度限制:pgvector 支持最多 2000 维的向量
- 内存使用:HNSW 索引会占用较多内存,需根据服务器配置调整参数
- 距离计算:余弦距离返回的是 1 - 余弦相似度,值越小越相似
- NULL处理:向量列可以包含 NULL 值,距离计算时 NULL 会返回 NULL
- 版本兼容:确保 pgvector 扩展版本与 PostgreSQL 版本兼容
通过以上配置和示例,您可以充分利用 pgvector 在 PostgreSQL 中实现高效的向量相似性搜索功能。
参考来源
- 2-PostgreSQL docker compose 安装教程-Pgvector
- Linux环境下基于Docker安装 PostgreSQL数据库并配置 pgvector
- docker安装pgvector、age和postgis
- docker安装的postgres同时安装postgis、pgvector 扩展
- pgvector docker部署测试