Skip to content

HNSW streaming KNN search support#138

Open
maximbogatyrev wants to merge 1 commit into
masterfrom
feature/hnsw-knn-streaming
Open

HNSW streaming KNN search support#138
maximbogatyrev wants to merge 1 commit into
masterfrom
feature/hnsw-knn-streaming

Conversation

@maximbogatyrev

Copy link
Copy Markdown

Добавлена поддержка HNSW streaming KNN — поиск без обязательных k и radius в базовых параметрах, с пагинацией через limit/offset на запросе. Соответствует доработке в основном reindexer-репозитории.

  • Разрешён пустой BaseKnnSearchParam при сериализации HNSW-параметров (allowEmpty)
  • Добавлена фабрика KnnParams.base() для streaming-режима
  • Обновлена валидация ef: если k не задан, достаточно ef > 0
  • Для BF/IVF по-прежнему требуется хотя бы один из k или radius
  • Добавлен тест testStreamingKnnHnsw_isOk (reference-запрос с k, streaming с limit/offset, проверка rank и post-filter)

API

// Streaming (без k/radius)
KnnParams.hnsw(KnnParams.base(), ef)
// обычный поиск
KnnParams.hnsw(KnnParams.k(k), ef)

throw new IllegalArgumentException("Minimal value of 'ef' must be greater than or equal to 'k'");
}
} else if (ef <= 0) {
throw new IllegalArgumentException("Minimal value of 'ef' must be greater than 0");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А откуда появилось вот это ограничение? Насколько я помню, в ядро для стриминг-режима можно передать ef=0 и там пройдёт выборка

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну, вообще вроде не должны проходить валидацию на этапе разбора knn-параметров (ни через десериализацию, ни через c++ query-builder):

void KnnSearchParams::Validate() const {
	// Empty 'k' and empty 'radius' both are allowed for the streaming KNN search over an HNSW index
	std::visit(
		overloaded{[](const KnnSearchParamsBase& p) { checkKNotZero(p); }, [](const BruteForceSearchParams& p) { checkKandRadius(p); },
				   [](const HnswSearchParams& p) {
					   checkKNotZero(p);
					   if (p.K() && p.Ef() < *p.K()) {
						   throw Error{errQueryExec, "Ef should not be less than k in hnsw query"};
					   }
					   if (p.Ef() < 1) {
						   throw Error{errQueryExec, "Value of 'ef' - {} is out of bounds: [1,{}]", p.Ef(),
									   std::numeric_limits<size_t>::max()};
					   }
				   },
				   [](const IvfSearchParams& p) {
					   checkKandRadius(p);
					   if (p.NProbe() == 0) {
						   throw Error{errQueryExec, "Nprobe should not be 0"};
					   }
				   }},
		toVariant());
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants