manual/russian/Searching/Hybrid_search.md
Гибридный поиск объединяет полнотекстовый (BM25) поиск с KNN векторным поиском в одном запросе, объединяя результаты с использованием Reciprocal Rank Fusion (RRF). Это позволяет использовать сильные стороны обоих методов извлечения: точность по ключевым словам от BM25 и семантическое понимание от векторного сходства.
Полнотекстовый поиск отлично справляется с точным соответствием ключевых слов и редкими терминами, но упускает концептуально похожий контент. Векторный поиск улавливает семантическое значение, но может быть зашумленным на неоднозначных запросах. Гибридный поиск объединяет оба подхода, поэтому документы, которые хорошо оцениваются по любому или обоим сигналам, оказываются на поверхности.
RRF — это алгоритм слияния, основанный на рангах. Он работает с позициями рангов, а не с исходными оценками, что позволяет избежать необходимости нормализации несовместимых шкал оценок (оценки BM25 неограничены; расстояния KNN имеют другую шкалу).
RRF_score(d) = SUM over all result sets r: weight_r / (rank_constant + rank_r(d))
Где:
d — это документrank_r(d) — это позиция документа (начиная с 1) в наборе результатов r (отсортированном по оценке этого извлекателя)rank_constant — это константа сглаживания (по умолчанию: 60, настраивается через опцию rank_constant)weight_r — это необязательный вес для каждого извлекателя (по умолчанию: 1.0)Если документ не появляется в конкретном наборе результатов, его вклад от этого набора равен 0.
rank_constant=60 используется по умолчанию.Объедините MATCH(...) и KNN(...) в предложении WHERE с OPTION fusion_method='rrf':
SELECT id, hybrid_score()
FROM t
WHERE match('machine learning')
AND knn(vec, (0.1, 0.1, 0.1, 0.1))
OPTION fusion_method='rrf';
POST /search
{
"table": "t",
"knn": {
"field": "vec",
"query_vector": [0.1, 0.1, 0.1, 0.1]
},
"query": { "match": { "title": "machine learning" } },
"options": { "fusion_method": "rrf" }
}
Это запускает текстовый поиск и KNN поиск как независимые параллельные подзапросы, а затем объединяет результаты с помощью RRF. Без fusion_method='rrf' запрос выполняется как обычный KNN поиск, отфильтрованный по текстовому соответствию (поведение до гибридного поиска).
В этом режиме до гибридного поиска ранжирование KNN по-прежнему имеет приоритет. Если knn_dist() доступна и вы не сортируете по ней явно, Manticore добавляет knn_dist() ASC в начало порядка сортировки. На практике ORDER BY weight() DESC становится вторичным критерием разрешения ничьих, а не глобальной сортировкой по BM25.
hybrid_score() — оценка слияния RRF (доступна только в гибридных запросах)weight() — оценка текстового соответствия BM25knn_dist() — векторное расстояние (минимум по всем KNN подзапросам, если их несколько)| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
fusion_method | строка | (нет) | Установите в 'rrf', чтобы включить гибридный поиск. Обязательно. |
rank_constant | целое число | 60 | Константа сглаживания в формуле RRF |
window_size | целое число | 0 (авто) | Сколько результатов извлекает каждый подзапрос перед слиянием. При 0 вычисляется автоматически на основе KNN k (с передискретизацией) и LIMIT запроса |
fusion_weights | кортеж | (все 1.0) | Веса для каждого подзапроса при оценке RRF |
-- Default rank_constant=60 (gentler ranking)
SELECT id, hybrid_score() FROM t
WHERE match('machine learning') AND knn(vec, (0.1, 0.1, 0.1, 0.1))
OPTION fusion_method='rrf';
-- rank_constant=10 (sharper top-rank differences)
SELECT id, hybrid_score() FROM t
WHERE match('machine learning') AND knn(vec, (0.1, 0.1, 0.1, 0.1))
OPTION fusion_method='rrf', rank_constant=10;
POST /search
{
"table": "t",
"knn": { "field": "vec", "query_vector": [0.1, 0.1, 0.1, 0.1] },
"query": { "match": { "title": "machine learning" } },
"options": { "fusion_method": "rrf", "rank_constant": 10 }
}
Стандартные фильтры WHERE работают вместе с гибридным поиском. Фильтры применяются как к текстовым, так и к KNN подзапросам:
<!-- example hybrid_filters --> <!-- intro -->SELECT id, category, hybrid_score()
FROM t
WHERE match('machine learning')
AND knn(vec, (0.1, 0.1, 0.1, 0.1))
AND category = 1
OPTION fusion_method='rrf';
POST /search
{
"table": "t",
"knn": { "field": "vec", "query_vector": [0.1, 0.1, 0.1, 0.1] },
"query": {
"bool": {
"must": [
{ "match": { "title": "machine learning" } },
{ "equals": { "category": 1 } }
]
}
},
"options": { "fusion_method": "rrf" }
}
По умолчанию результаты сортируются по hybrid_score() DESC. Вы можете переопределить это:
Этот раздел относится к истинным гибридным запросам, т.е. запросам с использованием OPTION fusion_method='rrf'. Без fusion_method='rrf' запрос, включающий KNN(...), не объединяется и остается с приоритетом KNN, поэтому ORDER BY weight() DESC не дает глобально отсортированного по весу набора результатов.
-- Sort by hybrid score ascending
SELECT id, hybrid_score() FROM t
WHERE match('machine learning') AND knn(vec, (0.1, 0.1, 0.1, 0.1))
ORDER BY hybrid_score() ASC
OPTION fusion_method='rrf';
-- Sort by text weight
SELECT id, weight() FROM t
WHERE match('machine learning') AND knn(vec, (0.1, 0.1, 0.1, 0.1))
ORDER BY weight() DESC, id ASC
OPTION fusion_method='rrf';
-- Sort by KNN distance
SELECT id, knn_dist() FROM t
WHERE match('machine learning') AND knn(vec, (0.1, 0.1, 0.1, 0.1))
ORDER BY knn_dist() ASC
OPTION fusion_method='rrf';
Если текстовый запрос не соответствует ни одному документу, только результаты KNN вносят вклад в оценку RRF:
SELECT id, hybrid_score() FROM t
WHERE match('xyznonexistent') AND knn(vec, (0.1, 0.1, 0.1, 0.1))
OPTION fusion_method='rrf';
-- Returns results ranked purely by KNN rank
Один гибридный запрос может объединять текстовый поиск с несколькими KNN поисками по разным векторным атрибутам. Все они объединяются через RRF:
<!-- example hybrid_multi_knn --> <!-- intro -->-- Three-way fusion: text + vec1 KNN + vec2 KNN
SELECT id, hybrid_score()
FROM t
WHERE match('machine learning')
AND knn(vec1, (0.1, 0.1, 0.1, 0.1))
AND knn(vec2, (1.0, 0.0, 0.0, 0.0))
OPTION fusion_method='rrf';
-- KNN-only fusion (no text), two vector searches
SELECT id, hybrid_score()
FROM t
WHERE knn(vec1, (0.1, 0.1, 0.1, 0.1))
AND knn(vec2, (1.0, 0.0, 0.0, 0.0))
OPTION fusion_method='rrf';
POST /search
{
"table": "t",
"knn": [
{ "field": "vec1", "query_vector": [0.1, 0.1, 0.1, 0.1] },
{ "field": "vec2", "query_vector": [1.0, 0.0, 0.0, 0.0] }
],
"query": { "match": { "title": "machine learning" } },
"options": { "fusion_method": "rrf" }
}
Несколько KNN поисков без fusion_method приводят к ошибке.
По умолчанию все подзапросы вносят равный вклад (вес 1.0). Чтобы придать разную важность текстовому и KNN поискам, используйте fusion_weights с явными псевдонимами:
SELECT id, hybrid_score()
FROM t
WHERE match('machine learning') AS text
AND knn(vec1, (0.1, 0.1, 0.1, 0.1)) AS dense1
AND knn(vec2, (1.0, 0.0, 0.0, 0.0)) AS dense2
OPTION fusion_method='rrf',
fusion_weights=(text=0.7, dense1=0.2, dense2=0.1);
POST /search
{
"table": "t",
"knn": [
{ "field": "vec1", "query_vector": [0.1, 0.1, 0.1, 0.1], "name": "dense1" },
{ "field": "vec2", "query_vector": [1.0, 0.0, 0.0, 0.0], "name": "dense2" }
],
"query": { "match": { "title": "machine learning" } },
"options": {
"fusion_method": "rrf",
"fusion_weights": { "query": 0.7, "dense1": 0.2, "dense2": 0.1 }
}
}
SQL:
AS alias для MATCH(...) и KNN(...), чтобы дать им имена. Неявных/псевдонимов по умолчанию нет.JSON:
"query" — это фиксированный псевдоним для полнотекстового подзапроса."name" для каждой записи KNN."query" конфликтует с текстовым псевдонимом и приводит к ошибке."name") не поддерживаются в fusion_weights.Вы можете указать веса только для некоторых подзапросов; остальные по умолчанию будут иметь вес 1.0:
-- Only boost text, KNN searches default to weight 1.0
SELECT id, hybrid_score()
FROM t
WHERE match('machine learning') AS text
AND knn(vec1, (0.1, 0.1, 0.1, 0.1)) AS dense1
AND knn(vec2, (1.0, 0.0, 0.0, 0.0)) AS dense2
OPTION fusion_method='rrf', fusion_weights=(text=2.0);
Для таблиц с настроенными авто-эмбеддингами на атрибуте float_vector, hybrid_match() предоставляет сокращенную запись, которая автоматически запускает как текстовый, так и KNN поиск из одной строки запроса:
-- Explicit vector field
SELECT id, hybrid_score() FROM t WHERE hybrid_match('machine learning', vec);
-- Auto-detect vector field (requires exactly one auto-embedding attribute)
SELECT id, hybrid_score() FROM t WHERE hybrid_match('machine learning');
-- With custom k and rank_constant
SELECT id, hybrid_score() FROM t
WHERE hybrid_match('machine learning', vec, {k=3})
OPTION rank_constant=10;
-- With attribute filter
SELECT id, hybrid_score() FROM t
WHERE hybrid_match('machine learning', vec) AND category=1;
hybrid_match() автоматически:
Требование: Векторный атрибут должен иметь настроенные model_name и from для авто-эмбеддингов. Без них hybrid_match() возвращает ошибку.
Для таблиц с авто-эмбеддингами свойство "hybrid" предоставляет сокращенную запись в JSON:
POST /search
{
"table": "hj",
"hybrid": { "query": "machine learning" }
}
POST /search
{
"table": "hj",
"hybrid": { "query": "machine learning", "field": "vec" }
}
POST /search
{
"table": "hj",
"hybrid": { "query": "machine learning" },
"options": { "rank_constant": 10 }
}
Свойство "hybrid" не может использоваться вместе с "knn".
Когда векторный атрибут имеет авто-эмбеддинги, вы можете использовать "query" (строка) вместо "query_vector" (массив) в объекте knn:
POST /search
{
"table": "ht",
"knn": { "field": "vec", "query": "machine learning", "k": 5 },
"query": { "match": { "title": "machine learning" } },
"options": { "fusion_method": "rrf" }
}
Строка автоматически преобразуется в эмбеддинг во время выполнения запроса. Без настроенных авто-эмбеддингов это возвращает ошибку.
Внутренне гибридный запрос разделяется на N+1 параллельных подзапросов:
knn(...)Все подзапросы выполняются параллельно. После завершения всех, RRF-слияние:
knn_dist() равной минимальному расстоянию по всем KNN подзапросам для каждого документаweight() из текстового подзапроса