PGVector 详解:为你的应用添加向量搜索 – wiki大全

PGVector 详解:为你的应用添加向量搜索

在当今数据驱动的世界中,传统基于关键词的搜索方式正日益显露出其局限性。当我们需要理解数据背后的“含义”或寻找概念上相似的信息时,仅仅依靠关键词匹配往往力不从心。这时,向量搜索(Vector Search)应运而生,它通过将数据转换为高维空间中的数值向量(即“嵌入”),允许我们根据语义相似性而非精确匹配来检索信息。而 PGVector,正是将这一强大能力直接带入我们熟悉的PostgreSQL数据库的利器。

什么是向量搜索?

想象一下,你不仅仅想搜索“苹果”这个词,而是想找到所有与“水果”或“健康食品”相关的概念,即使这些内容中并未明确提到“苹果”。向量搜索通过将文本、图片、音频等各种类型的数据转化为一个固定长度的数值列表(向量),并在多维空间中表示它们。语义上相似的数据点,它们的向量在空间中会彼此靠近。通过计算向量之间的距离或角度,我们就能衡量它们之间的相似度。

传统搜索的局限性:
* 关键词依赖: 无法理解词语的上下文和语义关联。
* 同义词/近义词问题: 需要手动维护大量的同义词列表。
* 跨模态搜索困难: 难以直接比较图片和文本的相似性。

PGVector的出现彻底改变了这一局面,它允许开发者在不引入独立向量数据库的情况下,直接在PostgreSQL中实现高效的向量存储和搜索。

PGVector 详解

什么是 PGVector?

PGVector 是一个开源的 PostgreSQL 扩展,它为 PostgreSQL 数据库带来了向量相似度搜索的能力。这意味着你可以在现有的关系型数据旁边,直接存储和查询高维向量,从而构建强大的语义搜索、推荐系统等功能。它将向量数据库的功能无缝集成到你熟悉的关系型数据库中,极大地简化了开发和部署流程。

核心功能

  1. vector 数据类型: PGVector 引入了专用的 vector 数据类型,用于存储高维数值数组。你可以根据你的嵌入模型输出的维度来定义这个类型,例如 VECTOR(1536)
  2. 相似度计算: 它提供了一系列操作符,用于计算向量之间的距离或相似度:
    • l2 distance (欧几里得距离,操作符:<->):衡量两个向量在空间中的直线距离,距离越小越相似。
    • cosine distance (余弦距离,操作符:<=>):衡量两个向量之间的角度,角度越小(余弦值越大)越相似。
    • inner product (内积,操作符:<%>):常用于推荐系统,内积越大越相似。
  3. 索引支持: 为了在大规模数据集上实现高效的相似度搜索,PGVector 支持两种主要的近似最近邻(ANN)索引:
    • IVFFlat: 适用于需要更高召回率和可控精度的场景。
    • HNSW (Hierarchical Navigable Small World): 提供更快的查询速度和更高的召回率,但索引构建时间可能稍长。
  4. 与 PostgreSQL 生态系统的无缝集成: 作为 PostgreSQL 的一个扩展,PGVector 充分利用了 PostgreSQL 的稳定性、事务性、备份恢复、安全性以及丰富的查询能力。你可以在一个 SQL 查询中同时进行关系型数据筛选和向量相似度搜索。

为你的应用添加向量搜索

将 PGVector 集成到你的应用中通常涉及以下几个核心步骤:

第一步:安装和启用 PGVector

首先,你需要一个 PostgreSQL 数据库实例(推荐版本 11 或更高)。

  1. 安装 PGVector:
    • 如果你使用 Docker,可以使用预构建的镜像,例如 pgvector/pgvector:pg16
    • 或者,你可以从源代码编译安装 PGVector 扩展。
  2. 启用扩展: 连接到你的 PostgreSQL 数据库,并执行以下 SQL 命令来启用 PGVector 扩展:
    sql
    CREATE EXTENSION IF NOT EXISTS vector;

第二步:生成向量嵌入

在能够存储和搜索向量之前,你需要将你的原始数据(如文本描述、图片特征等)转换为数值向量,这一过程称为生成嵌入(Generating Embeddings)。这通常需要借助机器学习模型。

  • 概念: 嵌入模型将复杂的非结构化数据映射到多维空间中的一个点。
  • 常用工具和模型:
    • OpenAI API: 提供了强大的文本嵌入模型(如 text-embedding-ada-002),易于使用。
    • Hugging Face Transformers: 提供了大量预训练的文本、图像等嵌入模型。
    • Word2Vec/Doc2Vec: 传统的词语或文档嵌入模型。

Python 示例(使用 OpenAI API 生成文本嵌入):

“`python
import openai

确保已设置 OPENAI_API_KEY 环境变量或直接赋值

openai.api_key = “YOUR_OPENAI_API_KEY”

def generate_embedding(text):
try:
response = openai.embeddings.create(
input=text,
model=”text-embedding-ada-002″ # 选择你的嵌入模型
)
return response.data[0].embedding
except Exception as e:
print(f”Error generating embedding: {e}”)
return None

示例

text_to_embed = “PGVector让向量搜索变得简单高效。”
embedding = generate_embedding(text_to_embed)
if embedding:
print(f”生成的嵌入向量维度:{len(embedding)}”)
# print(embedding[:5]) # 打印前5个维度示例
“`

第三步:存储向量数据

一旦你有了数据的嵌入向量,就可以在 PostgreSQL 中创建一个表来存储它们。该表需要一个 vector 类型的列。

sql
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
embedding VECTOR(1536) -- 替换为你的嵌入模型的实际维度
);

在上述示例中,1536 是 OpenAI text-embedding-ada-002 模型输出的维度。请根据你使用的模型调整。

接着,你可以将原始数据及其生成的嵌入向量插入到表中:
sql
INSERT INTO documents (content, embedding) VALUES
('向量数据库是处理非结构化数据的理想选择。', '[0.1, 0.2, 0.3, ..., 0.N]'), -- 这里的[...]代表完整的1536维向量
('PGVector 将向量搜索带入 PostgreSQL。', '[0.4, 0.5, 0.6, ..., 0.M]');

请注意,实际插入时,[0.1, 0.2, ..., 0.N] 应替换为完整的数值列表字符串。

第四步:执行相似度查询

要查找与某个查询最相似的文档,你需要首先生成查询文本的嵌入向量,然后使用 PGVector 的相似度操作符在 SQL 查询中进行比较。

Python 示例(结合 psycopg2 进行查询):

“`python
import psycopg2
import numpy as np # 用于处理向量,可选

… (假设 generate_embedding 函数和数据库连接已设置)

DB_HOST = “localhost”
DB_NAME = “your_database”
DB_USER = “your_user”
DB_PASSWORD = “your_password”

def get_db_connection():
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASSWORD
)
return conn

def semantic_search(query_text, limit=5):
query_embedding = generate_embedding(query_text)
if query_embedding is None:
return []

conn = get_db_connection()
cur = conn.cursor()
results = []
try:
    # 将 Python 列表转换为 PGVector 期望的字符串格式
    query_embedding_str = "[" + ",".join(map(str, query_embedding)) + "]"

    # 使用 '<->' (欧几里得距离) 或 '<=>' (余弦距离)
    cur.execute(
        "SELECT content, embedding <-> %s AS distance FROM documents ORDER BY distance LIMIT %s;",
        (query_embedding_str, limit)
    )
    results = cur.fetchall()
    print(f"\n查询 '{query_text}' 的结果:")
    for content, distance in results:
        print(f"  内容: '{content}', 距离: {distance:.4f}")
except Exception as e:
    print(f"查询出错: {e}")
    conn.rollback()
finally:
    cur.close()
    conn.close()
return results

示例查询

semantic_search(“人工智能和数据库的结合”)

``
在上述查询中,
ORDER BY distance` 通常用于按相似度排序,对于距离度量(如欧几里得距离),距离越小表示越相似;对于相似度度量(如余弦相似度),值越大表示越相似。

第五步:优化性能 – 建立索引

对于包含大量向量的表,不加索引的相似度搜索会非常慢。PGVector 提供了索引来加速查询。

  • 为什么需要索引? 全表扫描进行相似度计算的开销巨大,索引可以显著减少需要比较的向量数量。
  • 创建 IVFFlat 索引:
    sql
    CREATE INDEX ON documents USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);

    vector_l2_ops 指定使用欧几里得距离进行索引,你也可以选择 vector_cosine_opsvector_ip_opslists 参数需要根据你的数据集大小和查询需求进行调整。
  • 创建 HNSW 索引:
    sql
    CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);

    m 控制图中的连接数,ef_construction 影响索引构建时的精度。这些参数需要根据实际情况调优。

实际应用案例

PGVector 的强大功能使其在多种应用场景中大放异彩:

  • 语义搜索: 构建能够理解用户意图而非仅仅关键词的搜索引擎,例如文档检索、法律案例查询。
  • 推荐系统: 根据用户行为、商品描述等生成嵌入,推荐相似的商品、电影、音乐或文章。
  • 异常检测: 在日志、网络流量或传感器数据中,通过识别与“正常”模式的向量距离较大的异常点来检测异常。
  • 大语言模型(LLM)应用: 作为外部知识库(RAG – Retrieval Augmented Generation)的一部分,帮助 LLM 检索相关信息,减少幻觉,提供更准确的回答。

总结

PGVector 为 PostgreSQL 用户提供了一个无缝且高效的方式来集成向量搜索能力。它不仅利用了 PostgreSQL 强大的数据管理功能,还使得在关系型数据和非结构化数据之间建立语义连接成为可能。通过理解其核心概念、安装步骤和使用方法,开发者可以轻松地为自己的应用添加智能的向量搜索功能,从而开启全新的用户体验和业务洞察。随着 AI 和机器学习的不断发展,PGVector 无疑将在未来的数据架构中扮演越来越重要的角色。

这篇文章应该能满足用户的需求。The article is complete and details PGVector, vector search, its features, and how to integrate it into an application. I have provided a comprehensive explanation, including installation, embedding generation, data storage, querying, indexing, and real-world use cases, along with Python and SQL code examples.

I have completed the user’s request.

滚动至顶部