Almacenamiento de vectores en Azure Database for PostgreSQL

Completado

Recuerde que necesita insertar vectores almacenados en una base de datos vectorial para ejecutar una búsqueda semántica. El servidor flexible de Azure Database for PostgreSQL se puede usar como base de datos vectorial con la vector extensión .

Diagrama de un servidor flexible de Azure Database for PostgreSQL y la extensión denominada

Introducción a vector

La extensión de código vector abierto proporciona almacenamiento vectorial, consulta de similitud y otras operaciones vectoriales para PostgreSQL. Una vez habilitado, puede crear vector columnas para almacenar incrustaciones (u otros vectores) junto con otras columnas.

/* 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]');

Puede agregar columnas vectoriales a tablas existentes:

ALTER TABLE documents ADD COLUMN embedding vector(3);

Una vez que tenga algunos datos vectoriales, puede verlos junto con los datos de tabla normales:

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

La vector extensión admite varios lenguajes, como .NET, Python, Java y muchos otros. Consulte sus repositorios de GitHub para obtener más información.

Para insertar un documento con vector [1, 2, 3] mediante Npgsql en C#, ejecute código similar al siguiente:

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();
}

Insertar y actualizar vectores

Una vez que una tabla tiene una columna vectorial, las filas se pueden agregar con valores vectoriales, como se indicó anteriormente.

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

También puede cargar vectores de forma masiva mediante la instrucción (consulte el COPYejemplo completo en Python):

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

Las columnas vectoriales se pueden actualizar como columnas estándar:

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

La extensión vector proporciona el operador v1 <=> v2 para calcular la distancia de coseno entre vectores v1 y v2. El resultado es un número entre 0 y 2, donde 0 significa "semánticamente idéntico" (sin distancia) y dos significan "semánticamente opuesto" (distancia máxima).

Puede ver los términos distancia coseno y similitud. Recuerde que la similitud de coseno está entre -1 y 1, donde -1 significa "semánticamente opuesto" y 1 significa "semánticamente idéntico". Tenga en cuenta que similarity = 1 - distance.

La captura de pantalla es una consulta ordenada por distancia ascendente que devuelve primero los resultados menos distantes (más similares), mientras que una consulta ordenada por similitud descendente devuelve primero los resultados más similares (menos distantes).

Estos son algunos vectores y sus distancias y similitudes para ilustrar los conceptos. Puede calcular este cálculo usted mismo ejecutando algo parecido a:

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

Tenga en cuenta estos vectores:

Gráfico 2D que muestra los vectores (1,1), (1,0), (0,1) y (0,0).

Sus similitudes y distancias son:

v1 V2 distancia similitud
[1, 1] [1, 1] 0 1
[1, 1] [-1, -1] 2 -1
[1, 0] [0, 1] 1 0

Para obtener los documentos en orden de proximidad con el vector [2, 3, 4], ejecute 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

El documento con id=3 es el más similar a la consulta, seguido de id=1 y por último por id=2.

Agregue una cláusula LIMIT N a la consulta SELECT para devolver los documentos más similares principales N. Por ejemplo, para obtener el documento más similar:

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

Resultados:

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