[C API] Filter-aware Vamana search: evaluate the ID filter during graph traversal
Maintainer thường phản hồi trong vòng 5 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 15/100
Hướng nghiên cứu
Start with filtered_topk_search in bindings/c/src/filtered_search.hpp, which applies the filter only after batches are produced, and with the svs_id_filter_t interface and svs_index_search_topk in svs_c.h. The graph search itself, where admission and termination would need to change, lies outside the payload. Done means an opt-in mode that gates result admission inside the search, with new tests in bindings/c/tests/ for returned ids passing the filter, fewer than k results, and an exclusion filter, plus a recall benchmark against the batch path.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
Add an opt-in filtered search mode in which the ID filter decides which candidates enter the result set during the Vamana graph search, and the search's stopping rule counts only filter-passing results. Today svs_index_search_topk searches without the filter and filters the batches afterwards. The existing behaviour should stay the default.
Current behaviour
With an ID filter, filtered_topk_search (bindings/c/src/filtered_search.hpp:194-223 at 8285340) does the following:
- opens a batch iterator on the unfiltered index;
- requests batches of nearest candidates;
- calls
is_member()on each candidate after the batch is produced; - keeps going until
khits are found or the iterator is exhausted.
The graph search itself never sees the filter: its beam and its termination are driven by all candidates, whether they pass the filter or not. With a selective filter, most of the search effort goes into candidates that are then discarded. Batch sizing (estimate_batch_size) adapts to the observed hit rate, but the search beneath it stays unfiltered.
Reference: how hnswlib does it
In hnswlib's base-layer search (third_party/hnswlib/hnswalg.h:552-578 in eshenayo/valkey-search@91914c7):
- every closer candidate still goes into the traversal frontier (
candidate_set), so edge expansion is not gated by the filter; - the filter only decides whether a candidate is admitted to the result heap (
top_candidates); - because the stopping rule (
top_candidates.size() < ef || lowerBound > dist) is evaluated over filter-passing results only, a selective filter automatically makes the search go wider.
valkey-search's HNSW backend relies on this: a hybrid KNN query returns up to k matching results from one traversal.
Why it matters
In the valkey-search RFC for SVS_VAMANA (valkey-io/valkey-search#1256), reviewers called the lack of traversal-time filtering a significant limitation, because a high percentage of production vector queries are hybrid (vector + tag/numeric predicates). They also asked for it in time for the initial release:
- https://github.com/valkey-io/valkey-search/pull/1256#discussion_r3867012686
- https://github.com/valkey-io/valkey-search/pull/1256#discussion_r3824738901
The same mechanism serves a second use raised in that review: during an index rebuild, querying the old and new instances side by side and merging the results. That requires the old instance to exclude entries that have already been mutated in the new one, i.e. a predicate evaluated before an entry enters the result set (https://github.com/valkey-io/valkey-search/pull/1256#discussion_r3824932482).
Ask
- A filtered search mode for (dynamic) Vamana in which
is_member()gates admission to the result set inside the graph search, and termination and buffer management are computed over filter-passing results, as in hnswlib. - Expose it through the existing
svs_id_filter_tinterface, with no new callback type, selected opt-in: a new entry point, or a field in the search parameters.svs_index_search_topk's current behaviour stays the default, so other integrations are unaffected. - Results are at most
kper query, every returned id passes the filter, and the per-query count is reported throughoffsets/total_resultsas today.
The callback contract is unchanged: is_member() may be called from the searching thread for any candidate id and must be thread-safe, as it already is for the batch path.
Acceptance criteria
- With the new mode and a filter admitting 1-10% of ids, recall@k against an exact filtered ground truth is at least that of the current batch path, at equal or lower latency, on a benchmark both sides agree on.
- With a NULL filter, or with the mode not selected, results and latency are unchanged.
svs_c.hdocuments the mode and its contract.bindings/c/tests/covers: every returned id passes the filter; fewer thankresults when fewer thankids pass; and an exclusion-style filter (deny a given set of ids).
Related
- #415: documents the
filter_rate() <= 0contract of the current batch path, which valkey-search uses today. - #304: the batch iterator takes its search parameters from the parent index.
- Ngôn ngữ chính
- C++
- Star
- 241
- Fork
- 48
- Merge trung bình
- 4 ngày 21 giờ
- Pull request đã merge (30 ngày)
- 11
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của intel/ScalableVectorSearch
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
intel/ScalableVectorSearch#356 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 42/100
intel/ScalableVectorSearch#469 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
Add CI test for C API on ARMĐang mởenhancement
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 32/100
intel/ScalableVectorSearch#460 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
intel/ScalableVectorSearch#438 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
CI: tier the test matrix into PR / main / nightly to cut Actions minutesCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 32/100
intel/ScalableVectorSearch#432 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 5 ngày
Tất cả issue của intel/ScalableVectorSearch
Issue tương tự
-
runtime: lf_f128_mod is documented as fmodq (truncating) but implements floor-based modulo; unusedĐang mởinternal correctness low priority rt_lib
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 87/100
-
PriorityNotificationQueue::wakeUpAll() loses the wake-up for a thread that is not waiting yetCó thể đã có người làm @matejk đã nhận hôm nay. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
pocoproject/poco#5674 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug docs GUI
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
sonic-pi-net/sonic-pi#3609 ·
-
Unreachable code warningĐang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
SanderMertens/flecs#2395 ·
Maintainer thường phản hồi trong vòng 1 ngày