Manticore Search поддерживает возможность добавления эмбеддингов, сгенерированных моделями машинного обучения, к каждому документу, а затем выполнение поиска ближайших соседей по ним. Это позволяет создавать такие функции, как поиск по сходству, рекомендации, семантический поиск и ранжирование по релевантности на основе алгоритмов NLP, среди прочего, включая поиск по изображениям, видео и звуку.
Чтобы объединить векторный поиск KNN с полнотекстовым поиском для повышения релевантности, см. Гибридный поиск.
Эмбеддинг — это метод представления данных — таких как текст, изображения или звук — в виде векторов в многомерном пространстве. Эти векторы созданы таким образом, чтобы расстояние между ними отражало сходство представляемых ими данных. Этот процесс обычно использует алгоритмы, такие как word embeddings (например, Word2Vec, BERT) для текста или нейронные сети для изображений. Многомерная природа векторного пространства, со многими компонентами на вектор, позволяет представлять сложные и тонкие взаимосвязи между элементами. Их сходство измеряется расстоянием между этими векторами, часто с использованием методов, таких как евклидово расстояние или косинусное сходство.
Manticore Search позволяет выполнять поиск по векторам методом k-ближайших соседей (KNN) с использованием библиотеки HNSW. Эта функциональность является частью Manticore Columnar Library.
Для выполнения поиска KNN необходимо сначала настроить вашу таблицу. Векторы с плавающей точкой и поиск KNN поддерживаются только в таблицах реального времени (не в обычных таблицах). Таблица должна иметь хотя бы один атрибут типа float_vector, который служит вектором данных. Необходимо указать следующие свойства:
-
knn_type: Обязательная настройка; в настоящее время поддерживается толькоhnsw. -
knn_dims: Обязательная настройка, определяющая размерность индексируемых векторов. -
hnsw_similarity: Обязательная настройка, определяющая функцию расстояния, используемую индексом HNSW. Допустимые значения:L2- Квадрат L2IP- Скалярное произведениеCOSINE- Косинусное сходство
Примечание: При использовании сходства
COSINEвекторы автоматически нормализуются при вставке. Это означает, что сохраненные значения векторов могут отличаться от исходных входных значений, так как они будут преобразованы в единичные векторы (векторы с математической длиной/величиной 1.0) для обеспечения эффективных вычислений косинусного сходства. Эта нормализация сохраняет направление вектора, стандартизируя его длину. -
hnsw_m: Необязательная настройка, определяющая максимальное количество исходящих соединений в графе. По умолчанию 16. -
hnsw_ef_construction: Необязательная настройка, определяющая компромисс между временем построения и точностью. По умолчанию 200.
- SQL
- Config
create table test ( title text, image_vector float_vector knn_type='hnsw' knn_dims='4' hnsw_similarity='l2' );Query OK, 0 rows affected (0.01 sec)Самый простой способ работы с векторными данными — использование автоэмбеддингов. С этой функцией вы создаете таблицу с параметрами MODEL_NAME и FROM, а затем просто вставляете свои текстовые данные — Manticore автоматически генерирует эмбеддинги для вас.
При создании таблицы для автоэмбеддингов укажите:
MODEL_NAME: Модель эмбеддингов для использованияFROM: Какие поля использовать для генерации эмбеддингов (пустое значение означает все текстовые/строковые поля)API_KEY: Требуется для удаленных моделей (OpenAI, Voyage, Jina). Ключ API проверяется при создании таблицы путем выполнения реального API-запроса.API_URL: Опционально. Пользовательский URL конечной точки API. Если не указан, используется конечная точка провайдера по умолчанию (например,https://api.openai.com/v1/embeddingsдля OpenAI).API_TIMEOUT: Опционально. HTTP-таймаут в секундах для API-запросов. По умолчанию 10 секунд. Установите'0', чтобы использовать таймаут по умолчанию. Применяется как к запросам проверки при создании таблицы, так и к генерации эмбеддингов во время операций INSERT.
Поддерживаемые модели эмбеддингов:
| Тип модели | Пример | Требуется API-ключ | Примечания |
|------------|---------|-----------------|-------|
| Sentence Transformers | sentence-transformers/all-MiniLM-L6-v2 | Нет | Локальные модели на основе BERT, автоматически загружаются |
| Qwen | Qwen/Qwen3-Embedding-0.6B | Нет | Локальные модели семейства Qwen |
| Llama | TinyLlama/TinyLlama-1.1B-Chat-v1.0 | Нет | Локальные модели семейства Llama |
| Mistral | Locutusque/TinyMistral-248M-v2 | Нет | Локальные модели семейства Mistral |
| Gemma | h2oai/embeddinggemma-300m | Нет | Локальные модели семейства Gemma |
| OpenAI | openai/text-embedding-ada-002 | Да | API_KEY='<OPENAI_API_KEY>' |
| Voyage | Модели Voyage AI | Да | API_KEY='<VOYAGE_API_KEY>' |
| Jina | Модели Jina AI | Да | API_KEY='<JINA_API_KEY>' |
Требования к формату локальных моделей:
- Должны быть сохранены в формате
safetensors(только однофайловый) - Поддерживаемые семейства: Qwen, Llama, Mistral, Gemma
- Протестированные модели:
TinyLlama/TinyLlama-1.1B-Chat-v1.0,Locutusque/TinyMistral-248M-v2,Qwen/Qwen3-Embedding-0.6B,h2oai/embeddinggemma-300m - Другие модели
safetensorsтакже могут работать, но не гарантируется
Больше информации о настройке атрибута float_vector можно найти здесь.
- SQL
- Config
Использование sentence-transformers (API-ключ не требуется)
CREATE TABLE products (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='sentence-transformers/all-MiniLM-L6-v2' FROM='title'
);Использование локальных эмбеддингов Qwen (API-ключ не требуется)
CREATE TABLE products_qwen (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='Qwen/Qwen3-Embedding-0.6B' FROM='title' CACHE_PATH='/opt/homebrew/var/manticore/.cache/manticore'
);Использование OpenAI (требуется параметр API_KEY)
CREATE TABLE products_openai (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='openai/text-embedding-ada-002' FROM='title,description' API_KEY='...'
);Использование OpenAI с пользовательским URL API и таймаутом (опционально)
CREATE TABLE products_openai_custom (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='openai/text-embedding-ada-002' FROM='title,description'
API_KEY='...' API_URL='https://custom-api.example.com/v1/embeddings' API_TIMEOUT='30'
);Использование всех текстовых полей для эмбеддингов (FROM пуст)
CREATE TABLE products_all (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='sentence-transformers/all-MiniLM-L6-v2' FROM=''
);При использовании автоматических эмбеддингов вы можете:
- Пропустить векторное поле и позволить Manticore сгенерировать эмбеддинги из полей, перечисленных в
FROM - Явно предоставить собственный вектор для строки
- Указать
(), чтобы пропустить генерацию и сохранить вектор, состоящий из нулей
Если позже вы запустите ALTER TABLE ... REBUILD EMBEDDINGS, строки, которые в данный момент содержат нулевые векторы из (), также будут перегенерированы.
- SQL
Вставить только текстовые данные — эмбеддинги генерируются автоматически
INSERT INTO products (title) VALUES
('machine learning artificial intelligence'),
('banana fruit sweet yellow');Вставить вектор, предоставленный пользователем
INSERT INTO products (title, embedding_vector) VALUES
('machine learning artificial intelligence', (0.653448,0.192478,0.017971,0.339821));Вставить несколько полей — оба используются для создания эмбеддинга, если FROM='title,description'
INSERT INTO products_openai (title, description) VALUES
('smartphone', 'latest mobile device with advanced features'),
('laptop', 'portable computer for work and gaming');Вставить пустой вектор (без автоматической генерации; сохраняется нулевой вектор)
INSERT INTO products (title, embedding_vector) VALUES
('no embedding item', ());Поиск работает аналогичным образом — предоставьте ваш текстовый запрос, и Manticore сгенерирует эмбеддинги и найдет похожие документы:
- SQL
- JSON
SELECT id, knn_dist() FROM products WHERE knn(embedding_vector, 3, 'machine learning');+------+------------+
| id | knn_dist() |
+------+------------+
| 1 | 0.12345678 |
| 2 | 0.87654321 |
+------+------------+
2 rows in set (0.00 sec)В качестве альтернативы вы можете вручную вставлять предварительно вычисленные векторные данные, убедившись, что они соответствуют размерности, указанной вами при создании таблицы. Вы также можете вставить пустой вектор; это означает, что документ будет исключен из результатов векторного поиска.
Важно: При использовании hnsw_similarity='cosine' векторы автоматически нормализуются при вставке в единичные векторы (векторы с математической длиной/величиной 1.0). Эта нормализация сохраняет направление вектора, стандартизируя его длину, что необходимо для эффективных вычислений косинусного сходства. Это означает, что сохраненные значения будут отличаться от ваших исходных входных значений.
- SQL
- JSON
insert into test values ( 1, 'yellow bag', (0.653448,0.192478,0.017971,0.339821) ), ( 2, 'white bag', (-0.148894,0.748278,0.091892,-0.095406) );Query OK, 2 rows affected (0.00 sec)Теперь вы можете выполнить KNN-поиск, используя предложение knn в формате SQL или JSON. Оба интерфейса поддерживают одинаковые основные параметры, обеспечивая согласованный опыт независимо от выбранного формата:
- SQL:
select ... from <table name> where knn ( <field>, <query vector> [,<options>] ) - JSON:
POST /search { "table": "<table name>", "knn": { "field": "<field>", "query": "<text or vector>", "ef": <ef>, "rescore": <rescore>, "oversampling": <oversampling> } }
Параметры:
field: Имя атрибута вектора с плавающей запятой, содержащего векторные данные.k: Устаревшая опция. Используйтеlimitв запросе. Ранее использовалась для указания количества документов, которое должен вернуть один индекс HNSW. Однако фактическое количество документов, включенных в окончательные результаты, может варьироваться. Например, если система работает с таблицами реального времени, разделенными на дисковые чанки, каждый чанк может вернутьkдокументов, что приводит к общему количеству, превышающему указанноеk(так как совокупное количество будетnum_chunks * k). С другой стороны, окончательное количество документов может быть меньшеk, если после запросаkдокументов некоторые из них отфильтровываются на основе определенных атрибутов. Важно отметить, что параметрkне применяется к ramchunks. В контексте ramchunks процесс извлечения работает иначе, и поэтому влияние параметраkна количество возвращаемых документов неприменимо.query: (Рекомендуемый параметр) Поисковый запрос, который может быть:- Текстовой строкой: Автоматически преобразуется в эмбеддинги, если для поля настроены автоматические эмбеддинги. Вернет ошибку, если у поля нет автоматических эмбеддингов.
- Векторным массивом: Работает так же, как
query_vector.
query_vector: (Устаревший параметр) Поисковый вектор в виде массива чисел. Все еще поддерживается для обратной совместимости. Примечание: Используйте либоquery, либоquery_vector, но не оба в одном запросе.ef: необязательный размер динамического списка, используемого во время поиска. Более высокое значениеefприводит к более точному, но более медленному поиску. По умолчанию равно 10.rescore: Включает повторное вычисление релевантности для KNN (включено по умолчанию). Установите0в SQL илиfalseв JSON, чтобы отключить повторное вычисление. После завершения KNN-поиска с использованием квантованных векторов (с возможным передискретизацией) расстояния пересчитываются с исходными (полноразрядными) векторами, и результаты пересортировываются для повышения точности ранжирования.oversampling: Устанавливает коэффициент (значение с плавающей запятой), на который умножаетсяkпри выполнении KNN-поиска, что приводит к извлечению большего количества кандидатов, чем необходимо, с использованием квантованных векторов. По умолчанию применяетсяoversampling=3.0. Эти кандидаты могут быть позже переоценены, если повторное вычисление релевантности включено. Передискретизация также работает с неквантованными векторами. Поскольку она увеличиваетk, что влияет на работу индекса HNSW, это может вызвать небольшое изменение точности результатов.early_termination: Включает или отключает адаптивное раннее завершение во время обхода графа HNSW. Включено по умолчанию. Установите0в SQL илиfalseв JSON, чтобы отключить. Подробности см. в разделе Раннее завершение.
Документы всегда сортируются по расстоянию до поискового вектора. Любые дополнительные критерии сортировки, которые вы укажете, будут применены после этого основного условия сортировки. Для получения расстояния существует встроенная функция knn_dist().
- SQL
- JSON
select id, knn_dist() from test where knn ( image_vector, (0.286569,-0.031816,0.066684,0.032926), { ef=2000, oversampling=3.0, rescore=1 } );+------+------------+
| id | knn_dist() |
+------+------------+
| 1 | 0.28146550 |
| 2 | 0.81527930 |
+------+------------+
2 rows in set (0.00 sec)Индексы HNSW необходимо полностью загружать в память для выполнения поиска KNN, что может привести к значительному потреблению памяти. Чтобы уменьшить использование памяти, можно применить скалярное квантование — технику, которая сжимает высокоразмерные векторы, представляя каждую компоненту (измерение) ограниченным количеством дискретных значений. Manticore поддерживает 8-битное и 1-битное квантование, что означает сжатие каждой компоненты вектора с 32-битного числа с плавающей запятой до 8 бит или даже 1 бита, уменьшая использование памяти в 4 или 32 раза соответственно. Эти сжатые представления также позволяют выполнять более быстрые вычисления расстояний, так как больше компонент вектора может быть обработано за одну SIMD инструкцию. Хотя скалярное квантование вносит некоторую ошибку аппроксимации, это часто является оправданным компромиссом между точностью поиска и эффективностью использования ресурсов. Для ещё большей точности квантование можно комбинировать с пересчётом релевантности и избыточной выборкой: извлекается больше кандидатов, чем запрошено, и расстояния для этих кандидатов пересчитываются с использованием исходных 32-битных векторов с плавающей запятой.
Поддерживаемые типы квантования включают:
8bit: Каждая компонента вектора квантуется до 8 бит.1bit: Каждая компонента вектора квантуется до 1 бита. Используется асимметричное квантование, при котором векторы запросов квантуются до 4 бит, а хранимые векторы — до 1 бита. Этот подход обеспечивает более высокую точность, чем более простые методы, хотя и с некоторым компромиссом в производительности.1bitsimple: Каждая компонента вектора квантуется до 1 бита. Этот метод быстрее, чем1bit, но обычно менее точен.
- SQL
create table test ( title text, image_vector float_vector knn_type='hnsw' knn_dims='4' hnsw_similarity='l2' quantization='1bit');Query OK, 0 rows affected (0.01 sec)ПРИМЕЧАНИЕ: Поиск похожих документов по id требует наличия Manticore Buddy. Если это не работает, убедитесь, что Buddy установлен.
Поиск документов, похожих на конкретный, на основе его уникального ID, является распространённой задачей. Например, когда пользователь просматривает определённый элемент, Manticore Search может эффективно идентифицировать и отобразить список элементов, наиболее похожих на него в векторном пространстве. Вот как это можно сделать:
- SQL:
select ... from <table name> where knn ( <field>, <k>, <document id> ) - JSON:
POST /search { "table": "<table name>", "knn": { "field": "<field>", "doc_id": <document id>, "k": <k> } }
Параметры:
field: Это имя атрибута вектора с плавающей запятой, содержащего векторные данные.k: Это количество возвращаемых документов и ключевой параметр для индексов Hierarchical Navigable Small World (HNSW). Он указывает количество документов, которое должен вернуть один индекс HNSW. Однако фактическое количество документов, включённых в окончательные результаты, может варьироваться. Например, если система работает с таблицами реального времени, разделёнными на дисковые чанки, каждый чанк может вернутьkдокументов, что приводит к общему количеству, превышающему указанноеk(так как совокупное количество будетnum_chunks * k). С другой стороны, окончательное количество документов может быть меньшеk, если после запросаkдокументов некоторые из них отфильтровываются на основе определённых атрибутов. Важно отметить, что параметрkне применяется к ramchunks. В контексте ramchunks процесс извлечения работает иначе, и, следовательно, влияние параметраkна количество возвращаемых документов неприменимо.document id: ID документа для поиска сходства KNN.
- SQL
- JSON
select id, knn_dist() from test where knn ( image_vector, 5, 1 );+------+------------+
| id | knn_dist() |
+------+------------+
| 2 | 0.81527930 |
+------+------------+
1 row in set (0.00 sec)Manticore также поддерживает дополнительную фильтрацию документов, возвращаемых поиском KNN, либо по полнотекстовому соответствию, либо по фильтрам атрибутов, либо по обоим.
- SQL
- JSON
select id, knn_dist() from test where knn ( image_vector, 5, (0.286569,-0.031816,0.066684,0.032926) ) and match('white') and id < 10;+------+------------+
| id | knn_dist() |
+------+------------+
| 2 | 0.81527930 |
+------+------------+
1 row in set (0.00 sec)При комбинировании векторного поиска KNN с фильтрами атрибутов Manticore поддерживает две стратегии, которые отличаются тем, когда фильтр применяется относительно обхода графа HNSW.
-
Предфильтрация (по умолчанию;
prefilter=1(SQL) или"prefilter": true(JSON, по умолчанию)) передаёт фильтр непосредственно в сам обход HNSW. Каждый кандидат проверяется фильтром перед добавлением в кучу результатов — только соответствующие документы вносят вклад в итоговыеkрезультатов. Это уменьшает бесполезные вычисления расстояний и гарантирует возврат ровноkсоответствующих документов (при условии, что существуетkсоответствующих документов). -
Постфильтрация (
prefilter=0(SQL) или"prefilter": false(JSON)) сначала выполняет поиск KNN по всему набору данных, а затем применяет фильтр к результатам. Это безопасно и предсказуемо: граф HNSW обходится без помех, и фильтр влияет только на то, какие результаты возвращаются клиенту. Недостаток в том, что граф может тратить усилия на кандидатов, которые в итоге будут отброшены. При жёстком фильтре, соответствующем лишь небольшой доле документов, возвращённых результатовkможет быть значительно меньше запрошенного, потому что большинство кандидатов KNN не проходят фильтр.
Внутренне Manticore использует алгоритм на основе ACORN-1 для предварительной фильтрации. Наивная предварительная фильтрация просто пропускала бы несоответствующие узлы, что рискует потерей "мостовых" узлов, соединяющих иначе разделённые части графа HNSW, вызывая коллапс полноты при увеличении селективности фильтра. ACORN-1 избегает этого: когда узел не проходит фильтр, его соседи всё равно добавляются в очередь исследования. Это позволяет обходу обходить отфильтрованные узлы и поддерживать связность графа. Исследование ACORN-1 активируется автоматически, когда менее 60% от общего количества документов проходят фильтр.
Автоматический откат к полному перебору: При включенной предфильтрации Manticore оценивает, что будет дешевле: выполнить полный перебор расстояний по отфильтрованному подмножеству или обходить граф HNSW. Оценка сравнивает ожидаемое количество узлов, которые посетит HNSW, с количеством документов, прошедших фильтр. Если отфильтрованное множество достаточно мало, чтобы его прямое сканирование было быстрее, Manticore автоматически переключается на полный перебор, полностью пропуская HNSW. Это обеспечивает корректность и хорошую производительность даже при экстремальной селективности.
- SQL
- JSON
-- prefilter (default): filter applied during HNSW traversal (ACORN-1 used automatically)
SELECT id, knn_dist() FROM test
WHERE knn ( image_vector, (0.286569,-0.031816,0.066684,0.032926) )
AND price < 100;
-- postfilter: KNN runs over full dataset, filter applied to results
SELECT id, knn_dist() FROM test
WHERE knn ( image_vector, (0.286569,-0.031816,0.066684,0.032926), { prefilter=0 } )
AND price < 100;По умолчанию Manticore использует адаптивный алгоритм досрочного завершения во время обхода графа HNSW. Вместо того чтобы всегда исследовать полный набор кандидатов, определённый параметром ef, он отслеживает скорость, с которой новые кандидаты улучшают результирующий набор, и останавливается досрочно, когда эта скорость стабильно падает ниже порога. Это сокращает количество вычислений расстояний без значительного ухудшения качества результатов.
Досрочное завершение включено по умолчанию и автоматически отключается, когда k равно 10 или меньше, так как накладные расходы алгоритма не оправданы для таких маленьких результирующих наборов. Прирост производительности масштабируется с k — чем больше результирующий набор, тем больше вычислений расстояний можно сэкономить, остановившись раньше.
Обратите внимание, что передискретизация умножает эффективное k, используемое во время обхода HNSW, поэтому досрочное завершение также выигрывает от передискретизации: более высокое эффективное k означает больше кандидатов, которых потенциально можно пропустить.
Для явного управления досрочным завершением используйте опцию early_termination:
- SQL
- JSON
-- disable early termination
SELECT id, knn_dist() FROM test WHERE knn ( image_vector, (0.286569,-0.031816,0.066684,0.032926), { ef=200, early_termination=0 } );
-- enable early termination explicitly (default)
SELECT id, knn_dist() FROM test WHERE knn ( image_vector, (0.286569,-0.031816,0.066684,0.032926), { ef=200, early_termination=1 } );Когда следует отключать досрочное завершение:
- Когда точность результирующего набора критически важна и вы не можете позволить себе никакого приближения сверх того, что уже предоставляет HNSW.
- При использовании низких значений
k(примерно 30 или меньше), где досрочное завершение даёт мало преимуществ в производительности, но может снизить точность.