Хранение векторов в База данных Azure для PostgreSQL

Завершено

Помните, что для выполнения семантического поиска требуется внедрение векторных векторов, хранящихся в базе данных векторов. Гибкий сервер Базы данных Azure для PostgreSQL можно использовать в качестве векторной базы данных с расширением vector .

Схема гибкого сервера Базы данных Azure для PostgreSQL и расширения с именем vector. Рядом с ним находятся четыре хранимых вектора с 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 поддерживает несколько языков, таких как .NET, Python, Java и многие другие. Дополнительные сведения см. в репозиториях GitHub.

Чтобы вставить документ с вектором [1, 2, 3] с помощью Npgsql в C#, выполните следующий код:

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 оператору вычисление расстояния косинуса между векторами v1 и v2. Результатом является число от 0 до 2, где 0 означает "семантически идентичный" (без расстояния) и два означает "семантическая противоположность" (максимальное расстояние).

Вы можете увидеть термины косинусное расстояние и сходство. Напомним, что сходство косинуса составляет от -1 до 1, где -1 означает "семантическая противоположность" и 1 означает "семантически идентичны". Обратите внимание, что similarity = 1 - distance.

В результате запрос, упорядоченный по возрастанию расстояния, сначала возвращает наименьшие удаленные результаты (наиболее похожие), а запрос, упорядоченный по сходству, возвращает наиболее похожие (наименее удаленные) результаты сначала.

Ниже приведены некоторые векторы и их расстояния и сходство, чтобы проиллюстрировать понятия. Вы можете вычислить это вычисление самостоятельно, выполнив примерно следующее:

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

Рассмотрим следующие векторы:

2D-граф с векторами (1,1), (1,0), (0,1) и (0,0).

Их сходство и расстояния:

Версия 1 Версия 2 расстояние сходство
[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