vector. Использование векторных типов данных
Версия: 0.7.4
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: Отсутствуют.
Схема размещения:
ext
.
vector
– это расширение с открытым исходным кодом для реализации векторных типов хранения данных и поиска по сходству векторов для СУБД на основе PostgreSQL. Позволяет хранить векторы вместе с остальными данными в БД.
Поддерживает:
-
хранение векторов:
- с одинарной точностью;
- с половинной точностью;
- в двоичных и разреженных векторах;
-
точный и приблизительный поиск ближайших соседей для векторов по:
- расстоянию L2;
- внутреннему произведению;
- косинусному расстоянию;
- расстоянию L1;
- расстоянию Хэмминга (только для двоичных векторов);
- расстоянию Жаккарда (только для двоичных векторов);
Также поддерживается:
- соответствие ACID;
- восстановление на определенный момент времени;
- объединения и другие функции PostgreSQL.
vector
доступен для приложений на любом языке программирования с помощью клиента PostgreSQL.
Доработка
Добавление расширения vector
не проводилась.
Ограничения
Ограничения отсутствуют.
Установка
Расширение vector
доступно для продукта Pangolin, начиная с версии 6.4.0 и не требует дополнительных действий для сборки. Для того чтобы начать использовать расширение, необходимо один раз установить его в нужную БД командой:
CREATE EXTENSION vector;
Также возможно установить расширение в конкретную схему:
CREATE EXTENSION vector SCHEMA ext;
Для дальнейшего использования расширения, во избежание проблем, схема с расширением должна быть добавлена в пути поиска для УЗ, использующей векторы в своей работе:
SET search_path=public,ext;
Использование модуля
Быстрый старт
Создание таблицы с вектором в трех измерениях:
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
Вставка данных:
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
Поиск ближайшего соседа по расстоянию L2:
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
Также поддерживается:
- внутреннее произведение
<#>
; - косинусное расстояние
<=>
; - расстояние L1
<+>
.
<#>
возвращает отрицательное внутреннее произведение, поскольку PostgreSQL поддерживает только порядок ASC для сканирования индекса по оператору.
Хранение
Создание новой таблицы с векторным полем:
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
Также возможно добавление векторного поля к существующей таблице:
ALTER TABLE items ADD COLUMN embedding vector(3);
Также поддерживаются другие векторные типы:
- с половинной точностью;
- двоичные векторы;
- разреженные векторы.
Вставка данных:
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
Возможна загрузка векторов пачкой с использованием команды COPY
:
COPY items (embedding) FROM STDIN WITH (FORMAT BINARY);
Добавление векторов:
INSERT INTO items (id, embedding) VALUES (1, '[1,2,3]'), (2, '[4,5,6]')
ON CONFLICT (id) DO UPDATE SET embedding = EXCLUDED.embedding;
Обновление векторов:
UPDATE items SET embedding = '[1,2,3]' WHERE id = 1;
Удаление векторов:
DELETE FROM items WHERE id = 1;
Выполнение запросов
Поиск ближайшего соседа для вектора:
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
Поддерживаются следующие функции поиска:
<->
- расстояние L2;<#>
- (негативное) внутреннее произведение;<=>
- косинусное расстояние;<+>
- расстояние L1;<~>
- Расстояние Хэмминга (для бинарного типа);<%>
- расстояние Джаккарда (для бинарного типа).
Поиск ближайшего соседа для строки:
SELECT * FROM items WHERE id != 1 ORDER BY embedding <-> (SELECT embedding FROM items WHERE id = 1) LIMIT 5;
Получение строк на определенном расстоянии:
SELECT * FROM items WHERE embedding <-> '[3,1,2]' < 5;
Необходимо использовать совместно с ORDER BY
и LIMIT
для использования индекса.
Расстояния
Вычисление расстояний:
SELECT embedding <-> '[3,1,2]' AS distance FROM items;
Для внутреннего произведения необходимо умножать на -1, поскольку результат вычисления внутреннего произведения возвращает отрицательный результат:
SELECT (embedding <#> '[3,1,2]') * -1 AS inner_product FROM items;
Для косинусного расстояния необходимо результат вычисления вычитать из 1:
SELECT 1 - (embedding <=> '[3,1,2]') AS cosine_similarity FROM items;
Аггрегатные функции
Вычисление средних значений:
SELECT AVG(embedding) FROM items;
Вычисление средних значений с группировкой:
SELECT category_id, AVG(embedding) FROM items GROUP BY category_id;
Индексирование
По умолчанию vector выполняет точный поиск по ближайшему соседу, что обеспечивает идеальную воспроизводимость.
Возможно добавить индекс, чтобы использовать приблизительный поиск по ближайшему соседу, который ускоряет выполнение. В отличие от обычных индексов, можно увидеть отличающиеся результаты для одинаковых запросов после добавления приблизительного индекса.
Поддерживаются следующие типы индексов:
- HNSW;
- IVFFlat.
HNSW
Индекс HNSW создает многослойный граф. Он обеспечивает лучшую производительность запросов, по сравнению с IVFFlat (с точки зрения соотношения скорости и результата), но медленнее строится и использует больше памяти. Кроме того, данный индекс может быть создан без каких-либо данных в таблице, поскольку в нем нет шага обучения, как в IVFFlat.
Примеры добавления индекса для каждой функции расстояния, которую возможно использовать:
расстояние L2:
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);
Используйте halfvec_l2_ops
для halfvec (и аналогично с другими типами и функциями расстояния).
Внутреннее произведение:
CREATE INDEX ON items USING hnsw (embedding vector_ip_ops);
Косинусное расстояние:
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
Расстояние L1:
CREATE INDEX ON items USING hnsw (embedding vector_l1_ops);
Расстояние Хэмминга (только для бинарного типа векторов):
CREATE INDEX ON items USING hnsw (embedding bit_hamming_ops);
Расстояние Джаккарда (только для бинарного типа векторов):
CREATE INDEX ON items USING hnsw (embedding bit_jaccard_ops);
Поддерживаемые типы для данного индекса:
vector
- до 2000 измерений (2000-мерное пространство);halfvec
- до 4000 измерений (4000-мерное пространство);bit
- до 64000 измерений (64000-мерное пространство);sparsevec
- до 1000 ненулевых координат.
Опции индексирования
Указание параметров HNSW:
m
- максимальное количество подключений на слой (по умолчанию 16);ef_construction
- размер динамического списка кандидатов для построения графа (по умолчанию 64).
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 16, ef_construction = 64);
Более высокое значение ef_construction
обеспечивает лучшую воспроизводимость, однако страдают время построения индекса и скорость вставки.
Опции запросов
Размер динамического списка кандидатов для поиска (по умолчанию 40):
SET hnsw.ef_search = 100;
Более высокое значение обеспечивает лучшую воспроизводимость в обмен на скорость.
Использование SET LOCAL
внутри блока транзакции позволяет установить параметр для одного запроса:
BEGIN;
SET LOCAL hnsw.ef_search = 100;
SELECT ...
COMMIT;
Время построения индекса
Индексы строятся значительно быстрее, когда граф помещается в maintenance_work_mem
:
SET maintenance_work_mem = '8GB';
Когда граф больше не помещается, отображается уведомление:
NOTICE: hnsw graph no longer fits into maintenance_work_mem after 100000 tuples
DETAIL: Building will take significantly more time.
HINT: Increase maintenance_work_mem to speed up builds.
Не устанавливайте значение maintenance_work_mem
слишком высоким, чтобы не исчерпать свободную память на сервере.
Как и в случае с другими типами индексов, быстрее будет создать индекс после загрузки исходных данных. Также можно ускорить создание индекса, увеличив количество параллельных рабочих процессов (по умолчанию 2):
SET max_parallel_maintenance_workers = 7; -- plus leader
При большом количестве воркеров также может потребоваться увеличить значение max_parallel_workers
(по умолчанию 8).
Отображение прогресса индексирования
Начиная с версии ядра PostgreSQL 12+, возможно смотреть прогресс индексирования следующим запросом:
SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;
Построение индекса HNSW состоит из фаз:
- initializing;
- loading tuples.
IVFFlat
Индекс IVFFlat разбивает векторы на списки, а затем выполняет поиск в подмножестве тех списков, которые ближе всего расположены к вектору запроса. Он обеспечивает более быстрое построение и использует меньше памяти, чем HNSW, но обладает более низкой производительностью запроса (с точки зрения соотношения скорости и возврата).
Вот три ключа к достижению хорошей воспроизводимости:
- создание индекса после того, как в таблице появятся данные;
- подходящее количество списков - лучше всего начать с rows/1000 для 1 млн строк и sqrt(rows) для более чем 1 млн строк;
- при запросе указывать подходящее количество проб (чем больше, тем лучше для запоминания, чем меньше, тем лучше для скорости) - лучше всего начать с
sqrt(lists)
.
Ниже приведены примеры добавления индексов для каждой функции определения расстояния, которую планируется использовать.
Расстояние L2:
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);
Используйте halfvec_l2_ops для halfvec (и аналогично с другими типами и функциями расстояния).
Внутреннее произведение:
CREATE INDEX ON items USING ivfflat (embedding vector_ip_ops) WITH (lists = 100);
Косинусное расстояние:
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
Расстояние Хэмминга(только для бинарного типа):
CREATE INDEX ON items USING ivfflat (embedding bit_hamming_ops) WITH (lists = 100);
Поддерживаемые типы для данного индекса:
vector
- до 2000 измерений(2000-мерное пространство);halfvec
- до 4000 измерений(4000-мерное пространство);bit
- до 64000 измерений(64000-мерное пространство).
Опции запросов
Указание количества проб (по умолчанию 1):
SET ivfflat.probes = 10;
Более высокое значение обеспечивает лучшее запоминание в ущерб скорости, и его можно установить на количество списков для точного поиска ближайших соседей (в этот момент планировщик не будет использовать индекс).
Использование SET LOCAL
внутри транзакции позволяет установить параметр для одного запроса:
BEGIN;
SET LOCAL ivfflat.probes = 10;
SELECT ...
COMMIT;
Время построения индекса
Возможно ускорить создание индекса в больших таблицах за счет увеличения числа параллельных обработчиков (по умолчанию 2):
SET max_parallel_maintenance_workers = 7; -- plus leader
При большом количестве воркеров также может потребоваться увеличить значение max_parallel_workers
(по умолчанию 8).
Отображение прогресса индексирования
Начиная с версии ядра PostgreSQL 12+ возможно смотреть прогресс индексирования следующим запросом:
SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;
Фазы построения индекса IVFFlat:
- initializing;
- performing k-means;
- assigning tuples;
- loading tuples.
%
заполняется только на этапе загрузки кортежей.
Фильтрация
Существует несколько способов индексировать запросы ближайшего соседа с помощью предложения WHERE
:
SELECT * FROM items WHERE category_id = 123 ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
Создание индекса по одному или нескольким столбцам, используемым в директиве WHERE
для точного поиска:
CREATE INDEX ON items (category_id);
Или частичный индекс по векторному полю для приблизительного поиска:
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WHERE (category_id = 123);
Использование секционирования для приблизительного поиска по множеству различных значений столбцов, используемых в WHERE
:
CREATE TABLE items (embedding vector(3), category_id int) PARTITION BY LIST(category_id);
Типы векторов
Векторы с половинной точностью
Для хранения векторов с половинной точностью используется тип halfvec
:
CREATE TABLE items (id bigserial PRIMARY KEY, embedding halfvec(3));
Индекс вектора с половинной точностью, для уменьшения размера индекса:
CREATE INDEX ON items USING hnsw ((embedding::halfvec(3)) halfvec_l2_ops);
Получение ближайшего соседа:
SELECT * FROM items ORDER BY embedding::halfvec(3) <-> '[1,2,3]' LIMIT 5;
Двоичные векторы
Для хранения векторов в двоичном формате используется тип bit:
CREATE TABLE items (id bigserial PRIMARY KEY, embedding bit(3));
INSERT INTO items (embedding) VALUES ('000'), ('111');
Получение ближайшего соседа по расстоянию Хэмминга:
SELECT * FROM items ORDER BY embedding <~> '101' LIMIT 5;
Еще один способ:
SELECT * FROM items ORDER BY bit_count(embedding # '101') LIMIT 5;
Также поддерживается поиск по расстоянию Джаккарада (<%>
).
Двоичное квантование
Используйте выражение индексации для двоичного квантования:
CREATE INDEX ON items USING hnsw ((binary_quantize(embedding)::bit(3)) bit_hamming_ops);
Получение ближайшего соседа по расстоянию Хэмминга:
SELECT * FROM items ORDER BY binary_quantize(embedding)::bit(3) <~> binary_quantize('[1,-2,3]') LIMIT 5;
Переранжирование по исходным векторам для лучшей воспроизводимости:
SELECT * FROM (
SELECT * FROM items ORDER BY binary_quantize(embedding)::bit(3) <~> binary_quantize('[1,-2,3]') LIMIT 20
) ORDER BY embedding <=> '[1,-2,3]' LIMIT 5;
Разреженные векторы
Для хранения разреженных векторов используется тип sparsevec
:
CREATE TABLE items (id bigserial PRIMARY KEY, embedding sparsevec(5));
Вставка векторов:
INSERT INTO items (embedding) VALUES ('{1:1,3:2,5:3}/5'), ('{1:4,3:5,5:6}/5');
Разреженные векторы хранятся в формате {index1:value1,index2:value2}/dimensions
и отсчет начинается с 1 аналогично SQL-массивам. Данный формат векторов нужен, чтобы не тратить место на диске для хранения нулей.
Получение ближайшего соседа по расстоянию L2:
SELECT * FROM items ORDER BY embedding <-> '{1:3,3:1,5:2}/5' LIMIT 5;
Гибридный поиск
Использование совместно с полнотекстовым поиском PostgreSQL для гибридного поиска:
SELECT id, content FROM items, plainto_tsquery('hello search') query
WHERE textsearch @@ query ORDER BY ts_rank_cd(textsearch, query) DESC LIMIT 5;
Возможно использовать взаимное ранжирование или перекрестный кодер для объединения результатов.
Индексирование сабвекторов
Использование выражения индексирования для индексирования сабвекторов:
CREATE INDEX ON items USING hnsw ((subvector(embedding, 1, 3)::vector(3)) vector_cosine_ops);
Получение ближайшего соседа по косинусному расстоянию:
SELECT * FROM items ORDER BY subvector(embedding, 1, 3)::vector(3) <=> subvector('[1,2,3,4,5]'::vector, 1, 3) LIMIT 5;
Переранжирование по исходным векторам для лучшей воспроизводимости:
SELECT * FROM (
SELECT * FROM items ORDER BY subvector(embedding, 1, 3)::vector(3) <=> subvector('[1,2,3,4,5]'::vector, 1, 3) LIMIT 20
) ORDER BY embedding <=> '[1,2,3,4,5]' LIMIT 5;
Производительность
Тюнинг
Используйте инструмент, подобный PgTune, для установки начальных значений параметров сервера PostgreSQL. Например, shared_buffers
обычно должны занимать 25% памяти сервера. Можно найти конфигурационный файл с помощью команды:
SHOW config_file;
И проверить конкретную настройку:
SHOW shared_buffers;
Иногда необходимо рестартовать PostgreSQL для применения настройки.
Загрузка данных
Использование команды COPY
для загрузки данных порциями (пример):
COPY items (embedding) FROM STDIN WITH (FORMAT BINARY);
После загрузки данных возможно добавление индексов для улучшения производительности.
Индексирование
Обратите внимание на время построения индексов HNSW и IVFFlat.
В промышленных средах имеет смысл использовать конкурентное построение индекса для того, чтобы избежать блокировок:
CREATE INDEX CONCURRENTLY ...
Выполнение запросов
Используйте EXPLAIN ANALYZE
чтобы оценить производительность. Например:
EXPLAIN ANALYZE SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
Точный поиск
Чтобы ускорить выполнение запросов без индекса, увеличьте значение max_parallel_workers_per_gather
:
SET max_parallel_workers_per_gather = 4;
Если векторы нормализованы по длине (как эмбеддинги в OpenAI), используйте внутреннее произведение для достижения наилучшей производительности:
SELECT * FROM items ORDER BY embedding <#> '[3,1,2]' LIMIT 5;
Приблизительный поиск
Чтобы ускорить выполнение запросов с индексом IVFFlat, увеличьте количество инвертированных списков (за счет воспроизводимости):
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 1000);
Очистка
Очистка может ожидать индексы HNSW. Для ускорения процесса вакуума имеет смысл сперва выполнить REINDEX
:
REINDEX INDEX CONCURRENTLY index_name;
VACUUM table_name;
Мониторинг
Контролировать производительность возможно с помощью pg_stat_statements
(обязательно добавьте его в shared_preload_libraries
):
CREATE EXTENSION pg_stat_statements;
Получение запросов, которые выполнялись дольше всего:
SELECT query, calls, ROUND((total_plan_time + total_exec_time) / calls) AS avg_time_ms,
ROUND((total_plan_time + total_exec_time) / 60000) AS total_time_min
FROM pg_stat_statements ORDER BY total_plan_time + total_exec_time DESC LIMIT 20;
Контролируйте воспроизводимость, сравнивая результаты приблизительного поиска с точным поиском:
BEGIN;
SET LOCAL enable_indexscan = off; -- use exact search
SELECT ...
COMMIT;
Также возможно использование инструментов накопления статистики, таких как pg_profile
или performance_insight
.
Масштабирование
vector
масштабируется также, как PostgreSQL.
Вертикальное масштабирование достигается за счет увеличения объема памяти, процессора и хранилища в одном экземпляре. Используйте существующие инструменты для настройки параметров и мониторинга производительности.
Горизонтальное масштабирование достигается с помощью реплик или специальных библиотек (например, Citus) или другого подхода для сегментирования (пример - https://github.com/pgvector/pgvector-python/blob/master/examples/citus/example.py).
Языки программирования
Используйте vector из различных языков программирования через драйвер PostgreSQL. Возможно даже генерировать и сохранять вектора из приложения на одном языке, а использовать из другого.
Часто задаваемые вопросы
Как много векторов может быть сохранено в одной таблице?
Непартиционированные таблицы имеют ограничение 32 TB по умолчанию в PostgreSQL. Партиционированные таблицы могут иметь тысячи партиций такого размера.
Поддерживается ли репликация?
Да, pgvector
использует журнал предзаписи (WAL), который позволяет выполнять репликацию и восстановление на точку во времени.
Что делать, если я хочу индексировать векторы с более чем 2000 измерений?
Возможно использовать векторы с половинной точностью для увеличения до 4 000 измерений или бинарное квантование для увеличения до 64 000 измерений. Другой вариант — уменьшение размерности вектора.
Могу ли я сохранять векторы различной размерности в одной колонке?
Можно использовать тип без размерности, например vector
вместо vector(3)
:
CREATE TABLE embeddings (model_id bigint, item_id bigint, embedding vector, PRIMARY KEY (model_id, item_id));
Однако использовать индекс возможно только на строках с одинаковой размерностью векторов (используйте условия и частичное индексирование):
CREATE INDEX ON embeddings USING hnsw ((embedding::vector(3)) vector_l2_ops) WHERE (model_id = 123);
И пример выполнения такого запроса:
SELECT * FROM embeddings WHERE model_id = 123 ORDER BY embedding::vector(3) <-> '[3,1,2]' LIMIT 5;
Могу ли я хранить векторы с большей точностью?
Возможно использование типов double precision[]
или numeric[]
для сохранения векторов с большей точностью:
CREATE TABLE items (id bigserial PRIMARY KEY, embedding double precision[]);
-- use {} instead of [] for Postgres arrays
INSERT INTO items (embedding) VALUES ('{1,2,3}'), ('{4,5,6}');
При необходимости добавьте ограничение, контролирующее, что данные могут быть преобразованы в векторный тип и имеют ожидаемые размеры.
ALTER TABLE items ADD CHECK (vector_dims(embedding::vector) = 3);
Используйте индексирование по условию (для небольших размерностей):
CREATE INDEX ON items USING hnsw ((embedding::vector(3)) vector_l2_ops);
и выполняйте запросы:
SELECT * FROM items ORDER BY embedding::vector(3) <-> '[3,1,2]' LIMIT 5;
Должен ли индекс умещаться в памяти?
Нет, но, как и в случае с другими типами индексов, в этом случае производительность, скорее всего, повысится. Можно получить размер индекса с помощью:
SELECT pg_size_pretty(pg_relation_size('index_name'));
Почему запрос не использует индексы?
Запрос должен содержать ORDER BY и LIMIT, а ORDER BY должен быть результатом выполнения оператора вычисления дистанции (не выражения) в порядке ASC:
-- index
ORDER BY embedding <=> '[3,1,2]' LIMIT 5;
-- no index
ORDER BY 1 - (embedding <=> '[3,1,2]') DESC LIMIT 5;
Можно предложить планировщику использовать индекс для запроса с помощью:
BEGIN;
SET LOCAL enable_seqscan = off;
SELECT ...
COMMIT;
Также, если таблица имеет небольшие размеры, полное сканирование может быть быстрее.
Почему в запросе не используется параллельное сканирование таблицы?
Планировщик не учитывает внешнее хранение (TOAST) в оценке стоимости, что может удешевлять последовательное сканирование. Можно снизить стоимость параллельного сканирования запроса с помощью:
BEGIN;
SET LOCAL min_parallel_table_scan_size = 1;
SET LOCAL parallel_setup_cost = 1;
SELECT ...
COMMIT;
Или выберите встроенное хранение векторов:
ALTER TABLE items ALTER COLUMN embedding SET STORAGE PLAIN;
Почему после добавления индекса HNSW результатов по запросу становится меньше?
Результаты ограничены размером динамического списка кандидатов (hnsw.ef_search
). Результатов может быть еще меньше из-за неактивных кортежей или условий фильтрации в запросе. Рекомендуется задать для параметра hnsw.ef_search
значение, как минимум в два раза превышающее значение LIMIT
в запросе. Если нужно более 500 результатов, лучше использовать индекс IVFFlat.
Также обратите внимание, что векторы со значением NULL не индексируются (как и нулевые векторы для косинусного расстояния).
Почему после добавления индекса IVFFlat результатов по запросу становится меньше?
Вероятно, индекс был создан с использованием слишком малого количества данных для такого количества списков. Удалите индекс до тех пор, пока в таблице не будет больше данных.
DROP INDEX index_name;
Результаты также могут быть ограничены количеством проб (параметр ivfflat.probes
).
Также стоить иметь в виду, что векторы со значением NULL не индексируются (так же, как нулевые векторы для косинусного расстояния).
Техническое описание типов векторов
Тип vector
Каждый вектор занимает (4 * размерность + 8) байт в памяти. Каждый элемент представляет собой число с плавающей запятой одинарной точности (как тип real в Postgres), и все элементы должны быть конечными (без NaN, Infinity или -Infinity). Векторы могут иметь до 16 000 измерений.
Доступные операторы:
+
- поэлементное сложение;-
- поэлементное вычитание;*
- поэлементное умножение;||
- конкатенация;<->
- Евклидово расстояние(расстояние L2);<#>
- отрицательное внутреннее произведение;<=>
- косинусное расстояние;<+>
- расстояние городских кварталов(расстояние L1).
Доступные функции:
binary_quantize(vector) RETURN bit
- бинарное квантование;cosine_distance(vector, vector) RETURN double precision
- косинусное расстояние;inner_product(vector, vector) RETURN double precision
- внутреннее произведение;l1_distance(vector, vector) RETURN double precision
- расстояние L1;l2_distance(vector, vector) RETURN double precision
- расстояние L2;l2_normalize(vector) RETURN vector
- нормализация по Евклиду;subvector(vector, integer, integer) RETURN vector
- получение сабвектора;vector_dims(vector) RETURN integer
- размерность вектора;vector_norm(vector) RETURN double precision
- Евклидова норма.
Доступные агрегатные функции:
avg(vector) RETURN vector
- среднее;sum(vector) RETURN vector
- сумма.
Тип halfvec
Каждый вектор с половинной точностью занимает (2 * размерность + 8) байт в памяти. Каждый элемент представляет собой число с плавающей запятой половинной точности, и все элементы должны быть конечными (без NaN, Infinity или -Infinity). Векторы с половинной точностью могут иметь до 16 000 измерений.
Доступные операторы:
+
- поэлементное сложение;-
- поэлементное вычитание;*
- поэлементное умножение;||
- конкатенация;<->
- Евклидово расстояние(расстояние L2);<#>
- отрицательное внутреннее произведение;<=>
- косинусное расстояние;<+>
- расстояние городских кварталов(расстояние L1).
Доступные функции:
binary_quantize(halfvec) RETURN bit
- бинарное квантование;cosine_distance(halfvec, halfvec) RETURN double precision
- косинусное расстояние;inner_product(halfvec, halfvec) RETURN double precision
- внутреннее произведение;l1_distance(halfvec, halfvec) RETURN double precision
- расстояние L1;l2_distance(halfvec, halfvec) RETURN double precision
- расстояние L2;l2_normalize(halfvec) RETURN halfvec
- нормализация по Евклиду;subvector(halfvec, integer, integer) RETURN halfvec
- получение сабвектора;vector_dims(halfvec) RETURN integer
- размерность вектора;l2_norm(halfvec) RETURN double precision
- Евклидова норма.
Доступные агрегатные функции:
avg(halfvec) RETURN halfvec
- среднее;sum(halfvec) RETURN halfvec
- сумма.
Тип bit
Каждый бинарный вектор занимает (размерность/8 + 8) байт в памяти. Смотрите документацию на стандартный тип bit https://www.postgresql.org/docs/current/datatype-bit.html для получения подробностей.
Доступные операторы:
<~>
- расстояние Хэмминга;<%>
- расстояние Джаккарда.
Доступные функции:
hamming_distance(bit, bit) RETURN double precision
- расстояние Хэмминга;jaccard_distance(bit, bit) RETURN double precision
- расстояние Джаккарда.
Тип sparsevec
Каждый разреженный вектор занимает (8 * количество ненулевых элементов + 16) байт в памяти. Каждый элемент представляет собой число с плавающей запятой одинарной точности, и все элементы должны быть конечными (без NaN, Infinity или -Infinity). Разреженные векторы могут содержать до 16 000 ненулевых элементов.
Доступные операторы:
<->
- Евклидово расстояние(расстояние L2);<#>
- отрицательное внутреннее произведение;<=>
- косинусное расстояние;<+>
- расстояние городских кварталов(расстояние L1).
Доступные функции:
cosine_distance(sparsevec, sparsevec) RETURN double precision
- косинусное расстояние;inner_product(sparsevec, sparsevec) RETURN double precision
- внутреннее произведение;l1_distance(sparsevec, sparsevec) RETURN double precision
- расстояние L1;l2_distance(sparsevec, sparsevec) RETURN double precision
- расстояние L2;l2_normalize(sparsevec) RETURN sparsevec
- нормализация по Евклиду;l2_norm(sparsevec) RETURN double precision
- Евклидова норма.
Ссылки на документацию разработчика
Дополнительно поставляемый модуль vector: https://github.com/pgvector/pgvector.