Files
qdrant/docs/redoc
76f4f3e2ce Per-query IDF corpus for sparse vector search (#9661)
* Add per-query IDF corpus for sparse vector search

Let the caller choose, per query, which population sparse IDF statistics
are computed over. `params.idf` is either `"global"` (default, unchanged
behavior) or `{"corpus": <filter>}`, where the corpus filter is
independent of - and usually broader than - the retrieval filter.
Decoupling the two keeps the score scale stable when the retrieval
filter tightens: term importance is measured against a population the
user names, not against whatever subset the filter happens to select.

Design decisions:
- Corpus grammar is restricted to a conjunction (`must`) of `match`
  conditions on payload fields; loosening later is backward compatible.
- Strict mode validates the corpus filter like a read filter
  (unindexed fields rejected).
- `idf` on a vector without the IDF modifier is a validation error,
  never silently ignored.
- An empty corpus yields degenerate but corpus-scoped scores (smoothed
  IDF over N=0), never a fallback to global statistics - in multi-tenant
  collections a fallback would leak term statistics across tenants.

Implementation:
- QueryContext IDF stats are keyed by corpus, so one batch can mix
  requests with different corpora.
- Statistics come from the sparse index: df(term) is counted over the
  query terms' posting lists only, never by scanning stored vectors.
  Small corpora (under ~1/32 of the segment, by cardinality estimate)
  are kept as a sorted id list galloping through posting lists via
  skip_to; large ones as a dense membership mask filled streaming from
  the filtered-points iterator. A misestimated small corpus degrades
  into the mask.
- Exposed uniformly: REST (`params.idf`), gRPC (`IdfParams` message),
  edge python bindings; OpenAPI schema regenerated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Apply rustfmt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix clippy manual_is_multiple_of in sparse IDF corpus test.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Allow any filter as IDF corpus

Drop the must+match grammar restriction on the corpus filter. A
restriction enforced only as a validation step over the full Filter
type buys nothing; if a narrower corpus syntax is ever wanted, it
should be a dedicated API-level type instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix build: add memory field to SparseIndexConfig in idf corpus test

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: root <111755117+qdrant-cloud-bot@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-04 11:17:02 +02:00
..
2022-02-03 11:35:26 +01:00
2022-02-16 11:35:37 +01:00
2022-03-03 23:58:13 +01:00
2022-06-08 12:47:10 +02:00
2022-06-16 15:30:46 +02:00
2022-06-24 13:14:48 +02:00
2022-06-28 11:51:29 +02:00
2022-07-05 11:13:03 +02:00
2022-07-25 20:05:07 +02:00
2022-07-26 19:28:53 +02:00
2022-08-08 11:13:54 +02:00
2022-08-10 21:15:40 +02:00
2022-09-19 10:05:57 +02:00
2022-09-19 15:31:35 +02:00
2022-09-30 11:08:16 +02:00
2022-10-13 09:14:11 +02:00
2022-10-13 09:14:11 +02:00
2022-10-18 10:49:43 +02:00
2022-10-26 10:40:02 +02:00
2022-11-04 23:10:13 +01:00
2022-11-09 14:03:49 +01:00
2022-11-15 16:12:21 +01:00
2022-11-25 14:53:22 +01:00
2022-12-06 17:59:55 +01:00
2023-01-13 16:03:56 +01:00
2023-02-08 14:00:55 +01:00
2023-02-21 18:36:21 +01:00
2023-03-05 21:11:40 +01:00
2023-03-17 17:33:49 +01:00
2023-04-11 19:36:46 +02:00
2023-04-27 19:24:37 +02:00
2023-05-06 19:40:50 +02:00
2023-05-23 18:16:59 +02:00
2023-06-23 13:24:23 +02:00
2023-08-02 22:59:21 +02:00
2023-09-06 11:33:39 +02:00
2023-10-09 14:46:46 +02:00
2023-12-08 01:46:36 +01:00
2024-04-22 11:58:32 +02:00
2024-07-01 19:51:35 +02:00
2024-08-12 16:29:32 +02:00
2024-10-08 14:33:47 +02:00
2025-01-16 15:06:38 +01:00
2025-04-21 12:17:44 +02:00
2025-07-18 11:06:11 +02:00
2025-11-17 12:10:37 +01:00
2026-02-19 13:35:11 +01:00
2026-05-08 17:26:56 +02:00
2022-02-07 07:59:09 +01:00
2026-05-08 17:26:56 +02:00