Armazenar vetores no Banco de Dados do Azure para PostgreSQL
Lembre-se de que você precisa inserir vetores armazenados em um banco de dados vetorial para executar uma pesquisa semântica. O servidor flexível do Banco de Dados do Azure para PostgreSQL pode ser usado como um banco de dados vetorial com a extensão vector
.
Introdução à extensão vector
A extensão vector
de código aberto fornece armazenamento de vetor, consulta de similaridade e outras operações de vetor para o PostgreSQL. Depois que ela é habilitada, você pode criar colunas vector
para armazenar inserções (ou outros vetores) junto com outras colunas.
/* 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]');
Você pode adicionar colunas de vetor às tabelas existentes:
ALTER TABLE documents ADD COLUMN embedding vector(3);
Quando tiver alguns dados de vetor, você poderá vê-los junto com os dados normais da tabela:
# SELECT * FROM documents;
id | embedding
----+-----------
1 | [1,2,3]
2 | [2,1,3]
3 | [4,5,6]
A extensão vector
dá suporte a várias linguagens, como .NET, Python, Java e muitas outras. Confira os repositórios GitHub para saber mais.
Para inserir um documento com o vetor [1, 2, 3]
usando o Npgsql em C#, execute um código desta forma:
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();
}
Inserir e atualizar vetores
Depois que uma tabela tiver uma coluna de vetor, as linhas poderão ser adicionadas com valores de vetor, conforme indicado anteriormente.
INSERT INTO documents (embedding) VALUES ('[1,2,3]');
Você também pode carregar vetores em massa usando a instrução COPY
(confira o exemplo completo no Python):
COPY documents (embedding) FROM STDIN WITH (FORMAT BINARY);
As colunas de vetor podem ser atualizadas como colunas padrão:
UPDATE documents SET embedding = '[1,1,1]' where id = 1;
Realizar uma pesquisa de distância de cosseno
A extensão vector
fornece o operador v1 <=> v2
para calcular a distância de cosseno entre os vetores v1
e v2
. O resultado é um número entre 0 e 2, em que 0 significa “semanticamente idêntico” (nenhuma distância) e dois significa “semanticamente oposto” (distância máxima).
Você pode ver os termos distância e similaridade de cosseno. Lembre-se de que a semelhança de cosseno está entre -1 e 1, em que -1 significa “semanticamente oposto” e 1 significa “semanticamente idêntico”. Observe que similarity = 1 - distance
.
O resultado é que uma consulta ordenada pela distância crescente retorna os resultados menos distantes (mais semelhantes) primeiro, enquanto uma consulta ordenada pela similaridade decrescente retorna os resultados mais semelhantes (menos distantes) primeiro.
Aqui estão alguns vetores e as respectivas distâncias e semelhanças para ilustrar esses conceitos. Calcule isso por conta própria fazendo algo como:
SELECT '[1,1]' <=> '[-1,-1]';
Considere estes vetores:
As semelhanças e distâncias são:
v1 | V2 | distance | similaridade |
---|---|---|---|
[1, 1] |
[1, 1] |
0 | 1 |
[1, 1] |
[-1, -1] |
2 | -1 |
[1, 0] |
[0, 1] |
1 | 0 |
Para obter os documentos em ordem de proximidade com o vetor [2, 3, 4]
, execute esta consulta:
SELECT
*,
embedding <=> '[2,3,4]' AS distance
FROM documents
ORDER BY distance;
Resultados:
id | embedding | distance
----+-----------+-----------------------
3 | [4,5,6] | 0.0053884541273605535
1 | [1,2,3] | 0.007416666029069763
2 | [2,1,3] | 0.05704583272761632
O documento com id=3
é o mais semelhante à consulta, seguido logo após por id=1
e, por fim, por id=2
.
Adicione uma cláusula LIMIT N
à consulta SELECT
para retornar os N
documentos mais semelhantes. Por exemplo, para obter o documento mais semelhante:
SELECT
*,
embedding <=> '[2,3,4]' AS distance
FROM documents
ORDER BY distance
LIMIT 1;
Resultados:
id | embedding | distance
----+-----------+-----------------------
3 | [4,5,6] | 0.0053884541273605535