创建索引和查询向量

选择文档版本:

本文档介绍了如何使用存储的嵌入生成索引和查询嵌入。如需详细了解如何存储嵌入,请参阅存储向量嵌入

您可以使用 AlloyDB 创建 ScaNNIVFIVFFlatHNSW 索引。

准备工作

在开始创建索引之前,您必须完成以下前提条件。

  • 嵌入向量已添加到 AlloyDB 数据库中的表

  • 安装了基于 pgvectorvector 扩展程序版本 0.5.0 或更高版本(由 Google 针对 AlloyDB 进行扩展)。

    CREATE EXTENSION IF NOT EXISTS vector;
    
  • 如需生成 ScaNN 索引,请安装 alloydb_scann 扩展程序以及 vector 扩展程序。

    CREATE EXTENSION IF NOT EXISTS alloydb_scann;
    

创建索引

您可以为数据库中的表创建以下索引类型之一。

创建 HNSW 索引

AlloyDB 支持使用 AlloyDB pgvector 扩展程序创建基于图的 hnsw 索引,该索引可与原生 pgvector 搭配使用。使用 hnsw 索引会导致贪婪搜索,即不断遍历图,寻找查询向量的最近邻,直到找到最佳结果。与 IVF 相比,它可以提供更快的查询性能,但构建时间更长。

如需详细了解 HNSW 算法,请参阅分层可导航小世界

如需创建 hnsw 索引,请运行以下查询:

CREATE INDEX INDEX_NAME ON TABLE
  USING hnsw (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (m = NUMBER_OF_CONNECTIONS, ef_construction = 'CANDIDATE_LIST_SIZE');

替换以下内容:

  • INDEX_NAME:要创建的索引的名称,例如 my-hnsw-index

  • TABLE:要向其中添加索引的表。

  • EMBEDDING_COLUMN:用于存储 vector 数据的列。

  • DISTANCE_FUNCTION:要与此索引一起使用的距离函数。请按以下方式之一操作:

    • L2 距离:vector_l2_ops

    • 内积:vector_ip_ops

    • 余弦距离:vector_cosine_ops

  • NUMBER_OF_CONNECTIONS:图中每个节点的连接数上限。您可以先设置默认值 16,然后根据数据集的大小尝试更高的值。

  • CANDIDATE_LIST_SIZE:在图构建期间维护的候选项列表的大小,该列表会不断更新节点最近邻的当前最佳候选项。将此值设置为大于 m 值两倍的任何值,例如 64

如需查看索引编制进度,请使用 pg_stat_progress_create_index 视图:

SELECT * FROM pg_stat_progress_create_index;

phase 列会显示索引创建的当前状态,building graph 阶段会在索引创建后消失。

如需对索引进行调优以实现目标召回率和 QPS 平衡,请参阅hnsw 索引进行调优

运行查询

在将嵌入存储到数据库中并为其编制索引后,您可以开始使用 pgvector 查询功能进行查询。您无法使用 alloydb_scann 扩展程序运行批量搜索查询。

如需查找嵌入向量的语义最近邻,您可以运行以下示例查询,其中设置了在创建索引期间使用的相同距离函数。

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

替换以下内容:

  • TABLE:包含要与文本进行比较的嵌入的表。

  • INDEX_NAME:要使用的索引的名称,例如 my-scann-index

  • EMBEDDING_COLUMN:包含存储的嵌入的列。

  • DISTANCE_FUNCTION_QUERY:要用于此查询的距离函数。根据创建索引时使用的距离函数,选择以下各项之一:

    • L2 距离:<->

    • 内积:<#>

    • 余弦距离:<=>

  • EMBEDDING:您要为其查找存储的语义最近邻的嵌入向量。

  • ROW_COUNT:要返回的行数。

    如果您只想获得单个最佳匹配项,请指定 1

如需详细了解其他查询示例,请参阅查询

您还可以使用 embedding() 函数将文本转换为向量。您可以将向量应用于某个 pgvector 最近邻运算符(例如适用于 L2 距离的 <->),以查找具有语义最相似的嵌入的数据库行。

由于 embedding() 会返回 real 数组,因此您必须明确将 embedding() 调用转换为 vector,以便将这些值与 pgvector 运算符结合使用。

  CREATE EXTENSION IF NOT EXISTS google_ml_integration;
  CREATE EXTENSION IF NOT EXISTS vector;

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN::vector
    <-> embedding('MODEL_IDVERSION_TAG', 'TEXT')
    LIMIT ROW_COUNT

替换以下内容:

  • MODEL_ID:要查询的模型的 ID。

    如果您使用的是 Vertex AI Model Garden,请将 text-embedding-005 指定为模型 ID。这些是 AlloyDB 可用于文本嵌入的云端模型。如需了解详情,请参阅文本嵌入

  • 可选:VERSION_TAG:要查询的模型的版本标记。在标记前面添加 @

    如果您将某个 text-embedding 英语模型与 Vertex AI 搭配使用,请指定模型版本中列出的某个版本标记,例如 text-embedding-005

    Google 强烈建议您始终指定版本标记。如果您未指定版本标记,AlloyDB 会始终使用最新的模型版本,这可能会导致意外结果。

  • TEXT:要转换为向量嵌入的文本。

后续步骤