在 Azure Database for PostgreSQL 中存储矢量

已完成

回想一下,你需要嵌入存储在矢量数据库中的矢量来运行语义搜索。 Azure Database for PostgreSQL 灵活服务器可通过 vector 扩展用作矢量数据库

Azure Database for PostgreSQL 灵活服务器和名为“矢量”的扩展的关系图。旁边是四个具有 n 维和任意数值的存储的矢量。

vector 简介

开放源代码 vector 扩展为 PostgreSQL 提供矢量存储、相似度查询和其他矢量操作。 启用后,可以创建 vector 列来存储嵌入(或其他矢量)以及其他列。

/* Enable the extension. */
CREATE EXTENSION vector;

/* Create a table containing a 3d vector. */
CREATE TABLE documents (id bigserial PRIMARY KEY, embedding vector(3));

/* Create some sample data. */
INSERT INTO documents (embedding) VALUES
('[1,2,3]'),
('[2,1,3]'),
('[4,5,6]');

可以将矢量列添加到现有表:

ALTER TABLE documents ADD COLUMN embedding vector(3);

获得一些矢量数据后,可以将它们和普通表数据一起查看:

# SELECT * FROM documents;
 id | embedding
----+-----------
 1 | [1,2,3]
 2 | [2,1,3]
 3 | [4,5,6]

vector 扩展支持多种语言,例如 .NETPythonJava 和其他许多语言。 有关详细信息,请参阅其 GitHub 存储库

要在 C# 中使用 Npgsql 插入包含矢量 [1, 2, 3] 的文档,请运行如下所示的代码:

var sql = "INSERT INTO documents (embedding) VALUES ($1)";
await using (var cmd = new NpgsqlCommand(sql, conn))
{
  var embedding = new Vector(new float[] { 1, 2, 3 });
  cmd.Parameters.AddWithValue(embedding);
  await cmd.ExecuteNonQueryAsync();
}

插入和更新矢量

表具有矢量列后,可以使用矢量值添加行,如前所述。

INSERT INTO documents (embedding) VALUES ('[1,2,3]');

还可以使用 COPY 语句批量加载矢量(请参阅使用 Python 的完整示例):

COPY documents (embedding) FROM STDIN WITH (FORMAT BINARY);

可以像标准列一样更新矢量列:

UPDATE documents SET embedding = '[1,1,1]' where id = 1;

vector 扩展提供了 v1 <=> v2 运算符来计算矢量 v1v2 之间的余弦距离。 结果是介于 0 和 2 之间的数字,其中 0 表示“语义上完全相同”(无距离),2 表示“语义上相反”(最大距离)。

可以看到术语余弦距离和相似度。 回想一下,余弦相似度介于 -1 和 1 之间,其中 -1 表示“语义上相反”,1 表示“语义上相同”。请注意 similarity = 1 - distance

结果是按距离升序排序的查询首先返回距离最近(最相似)的结果,而按相似度降序排序的查询首先返回最相似(距离最近)的结果。

下面是用于说明概念的一些矢量及其距离和相似度。 可以通过运行如下所示的内容自行计算此计算:

SELECT '[1,1]' <=> '[-1,-1]';

请考虑以下矢量:

显示矢量 (1,1)、(1,0)、(0,1) 和 (0,0) 的 2D 图形。

它们的相似度和距离如下:

v1 V2 distance 相似性
[1, 1] [1, 1] 0 1
[1, 1] [-1, -1] 2 -1
[1, 0] [0, 1] 1 0

要按与矢量 [2, 3, 4] 接近程度的顺序获取文档,请运行以下查询:

SELECT
  *,
  embedding <=> '[2,3,4]' AS distance
FROM documents
ORDER BY distance;

结果:

 id | embedding |   distance
----+-----------+-----------------------
 3 | [4,5,6] | 0.0053884541273605535
 1 | [1,2,3] | 0.007416666029069763
 2 | [2,1,3] | 0.05704583272761632

包含 id=3 的文档与查询最相似,然后是 id=1,最后则是 id=2

LIMIT N 子句添加到 SELECT 查询以返回最相似的前 N 个文档。 例如,要获取最相似的文档:

SELECT
  *,
  embedding <=> '[2,3,4]' AS distance
FROM documents
ORDER BY distance
LIMIT 1;

结果:

 id | embedding |   distance
----+-----------+-----------------------
 3 | [4,5,6] | 0.0053884541273605535