* Remove deprecated search/recommend/discover endpoints from OpenAPI
Remove deprecated REST API endpoint definitions from the OpenAPI
generator. These endpoints were deprecated in v1.13.3 (`f4ced2567`,
#5907, 2025-01-30) in favor of the universal `/points/query` endpoint:
- POST /points/search
- POST /points/search/batch
- POST /points/search/groups
- POST /points/recommend
- POST /points/recommend/batch
- POST /points/recommend/groups
- POST /points/discover
- POST /points/discover/batch
Also removes the corresponding request types from the schema generator
and updates the expected API count in the consistency check.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Migrate OpenAPI integration tests to /points/query
The deprecated /points/search, /points/recommend and /points/discover
endpoints (along with their /batch and /groups variants) were removed
from the OpenAPI spec, which caused validation failures in the Python
integration test harness.
This commit migrates the affected tests to the universal /points/query
endpoint:
- Delete tests dedicated to the deprecated endpoints:
test_recommend.py, test_discover.py, test_multicollection_reco.py,
test_recommendation_multivector.py
- Refactor remaining tests to call /points/query (and /query/batch,
/query/groups), translating request bodies (vector -> query / using,
positive/negative -> query.recommend, target/context -> query.discover)
and unwrapping the new result.points response shape.
- Drop equivalence assertions against the now-removed legacy endpoints.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Relax non-empty assertions in migrated recommend/discover tests
The previous migration added `len(...) > 0` assertions to tests that
previously only checked equivalence between the deprecated and new
API. These assertions are too strict because the parametrized
`query_filter` cases legitimately produce empty result sets.
Drop the `> 0` assertion and rely on `request_with_validation` to
verify the response is well-formed and HTTP OK.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Migrate remaining OpenAPI tests off deprecated search endpoints
Tests added to dev after the original migration was written still call
/points/search and /points/recommend/groups through
`request_with_validation`, which resolves the endpoint against the
OpenAPI spec and therefore breaks once the endpoint is not in the spec:
- test_turbo4_storage.py, test_sparse_idf_corpus.py, test_validation.py:
translate /points/search to /points/query (vector{name,vector} ->
query + using, result -> result.points).
- test_group.py: drop the /points/recommend/groups half of the
lookup_from validation test in favour of the query equivalent.
test_sparse_idf_corpus.py's test_query_api_supports_idf_corpus goes
away: with the helper on /points/query every test in the file now
exercises what it asserted.
Also record why test_recommend_group cannot assert on its groups: it
uses every point in the collection as a recommend example, so all of
them are excluded and the result is legitimately empty.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Regenerate openapi.json without the deprecated search endpoints
Drops the 8 deprecated paths and the request schemas that only they
referenced: Search/Recommend/Discover request (+Batch, +Groups) types
and their exclusive dependencies (NamedVector, NamedSparseVector,
NamedVectorStruct, UsingVector, RecommendExample, ContextExamplePair).
Regenerated output is a strict subset of the previous spec, and every
remaining $ref still resolves.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Deprecate the search/recommend/discover RPCs in gRPC
The REST counterparts have carried `deprecated: true` since v1.13.3 and
are now gone from the OpenAPI spec, while the gRPC RPCs never got any
deprecation annotation at all. Mark all 8 with `option deprecated = true`
so generated clients warn, and point each doc comment at its `Query`
replacement.
tonic puts `#[deprecated]` on the generated client methods only; the
server trait gets the doc comment alone, so our own `impl` is unaffected.
The RPCs keep serving traffic — this is annotation only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Restore the deleted recommend/discover suites on /points/query
The earlier migration deleted these four files outright, but the
query-side tests it left behind are all shallow smoke tests
(`len(result) > 0`, `"points" in result[0]`). The deleted ones carried
invariants with no query-API equivalent anywhere, so deleting them was a
real loss of coverage rather than de-duplication:
- test_recommend.py: default strategy equals average_vector; batch
results identical to sequential singles across six request shapes;
best_score with only negatives yields all-negative scores; best_score
with a single positive orders identically to a nearest query; raw
vectors as examples equal ids as examples.
- test_discover.py: context-only scores are all <= 0; target-only orders
identically to a nearest query but scores differently; with a fixed
context the integer part of the score is stable while the decimal part
moves, and vice versa with a fixed target; batch equals singles;
lookup_from by id equals by vector.
- test_multicollection_reco.py: cross-collection lookup_from, plus
wrong-vector-size, unknown-collection and unknown-vector rejections.
- test_recommendation_multivector.py: the same recommend invariants over
a max_sim multivector collection, which the query suite never covered.
Only test_recommend_missing_lookup_from_collection_with_raw_vector is
dropped as genuinely redundant — test_query.py's
test_query_missing_lookup_from_collection covers query, query/batch and
prefetch.
Two request-shape differences the translation had to absorb:
- Giving no examples at all is 422 (a RecommendInput validation rule),
where the legacy API reported 400 from the query itself. A malformed
example, such as an empty vector, is still 400.
- DiscoverInput requires the `context` key and accepts only an explicit
null to mean "no context", so target-only discover must spell it out.
The legacy API let it be omitted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
These tests rely on the collection size stats cache being refreshed to
detect that a size limit has been exceeded. Without wait=true, upsert
operations are written to WAL and acknowledged immediately without being
applied to segments. When the cache refreshes, it reads segment data
which may not yet reflect the pending WAL operations, causing the size
check to see stale values and not reject the request.
Adding wait=true ensures operations are applied to segments before the
response returns, so the cache refresh sees the correct sizes.
Co-authored-by: Cursor Agent <agent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: add search_max_batchsize to strict mode config
* added test case for search_max_batchsize
* Changes for fixing CI issue dure openapi
* Modify check_strict_mode_batch
---------
Co-authored-by: Arnaud Gourlay <arnaud.gourlay@gmail.com>
* [strict-mode] Add max number of payload index count
* improve docs and validation for StrictModeConfig
* fix from coderabbit
* test blocking access to payload indexes
* polish test
* add `"match": { "phrase": ... }` condition
* gen grpc and openapi
* [phrase matching] expose `phrase_matching` flag in rest and grpc (#6620)
* expose setting in rest and grpc
* phrase matching openapi test
* regen openapi
* [phrase matching] Text index fixes (#6730)
* allow rocksdb-based immutable text index
* fix repeated-token phrases
* fmt
* Update OpenAPI spec
---------
Co-authored-by: timvisee <tim@visee.me>
* add repeated word case in openapi test
* [phrase match | strict mode] Allow phrase condition when enabled in index (#6749)
* allow phrase filter when index is present
* prettier error message
* clippppppy
---------
Co-authored-by: timvisee <tim@visee.me>
* Strict mode allows fullscan for multitenant payload index
* different error for missing payload index in multitenant case
* handle payload_m
* add simple test
* handle hnsw.m not set
* add another simple test
* fix test
* fallback to global HSNW config
* new error status code
* do not block on global HNSW and improver error reporting
* clearer error reporting
* review fixes
* fix test error messages
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* Fix UnindexedField infra to handle lookup&range index requirements
* more generic approach
* better test
* restore
* small unit test for sanity
* review nits
* Do not recommend parametrized index
---------
Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
* consider length of multivectors for rate limiter
* add openapi test
* organize imports
* better cost estimation for sparse vectors
* restore groups openapi test
* address @timvisee's review
* Fix consensus test
* move problems.rs to collection crate
* change type on datetime_key expression
* extract from expression
* check for unindexed fields in formula
* clippy
* dedup code
* Only implement verification for `CollectionQuery` types (#6319)
* verify CollectionQuery's Prefetch
* remove implementation for REST query
* remove implementation for REST query groups
* add basic openapi test
* Retry-After on rate limiter hit for REST API
* fix tests
* Ceil retry after seconds number so clients don't retry too early
* Relax retry after time requirement a bit in case CI machines are slow
* Add rate limit test, test retry after if we replanish within a second
* Report time to wait in rate limit error
---------
Co-authored-by: timvisee <tim@visee.me>
* Add limits for filter and conditions
* clippy
* Review remarks + nested condition test
* Fix opnapi specs
* Improve error message by giving info about limits and usage
* Strict mode config: Max collection size
* api specs
* Add tests + set/update payload check
* Improve function names and add comments
* rename config to separate vectors and payload
* fix tests
* Adjust configs docs
* add benchmark
* improve performance by caching shard info
* add bench for size_info() and fix tests
* Also limit the batch-size for vector updates (#5508)
* Also limit the batch-size for vector updates
* clippy
* add lost commit
* Load cache on collection initialization
* add unit type to parameter name
* fix renaming in test
* clearer error message
* fix test
* review remarks
* remove unused function for now
---------
Co-authored-by: Arnaud Gourlay <arnaud.gourlay@gmail.com>
Collection name under test is equal to the test module name, without `.py` suffix.
* Helps by debugging/tracing failed tests and find relevant logs lines in qdrant log files
* Opens up a possibility to run tests in parallel, given that there are no data sharing
between test modules
Change details:
* defined module scoped `collection_name` fixture in `conftest.py`
* removed `collection_name` module variable
* each test signature modified to declare the dependency to `collection_name` fixture
* `@pytest.mark.parametrize` migrated to `@pytest-cases.parametrize` in cases when
`collection_name` was used as the value