feat: add hybrid search for Chroma - #2677
Open
mattfreshwaters wants to merge 20 commits into
Open
Conversation
mattfreshwaters
marked this pull request as draft
June 25, 2026 13:58
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
mattfreshwaters
commented
Jun 25, 2026
mattfreshwaters
commented
Jun 25, 2026
mattfreshwaters
commented
Jun 25, 2026
mattfreshwaters
marked this pull request as ready for review
June 26, 2026 18:36
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds opt-in hybrid search (vector + BM25 keyword, fused via weighted Reciprocal Rank Fusion) to
ChromaVectorDatabaseEngine, plus the supporting work to make Chroma usable on current versions: the v2 REST API and metadata filter support. Controlled by an SMSS flag — engines without it are unaffected, fully backwards compatible.Requires Chroma v2 (the v1 API is removed in Chroma 1.x). Consolidates the intent of #1481 (v2 connection) and #179 (metadata filters) into one change.
Changes Made
/api/v2/tenants/{tenant}/databases/{db}/collections/...). New optional SMSS keysTENANT/DB_NAME(defaultdefault_tenant/default_database).filters/metaFiltersare translated to a Chromawhereclause via the newChromaVectorQueryFilterTranslationHelper— recursive$and/$orwith$eq/$in/$ne/$nin/$gt/$gte/$lt/$lte.USE_HYBRID_SEARCH=true(defaultsfalse). Fetches a vector candidate pool, scores each candidate's stored content with BM25 (Lucenek1=1.2,b=0.75), and fuses vector + keyword ranks with weighted RRF (k=60). Tunable viaHYBRID_VECTOR_WEIGHT(default0.5) andHYBRID_KEYWORD_GATE_THRESHOLD(default0.0); falls back to pure vector when the query matches no candidate text. Respects filters.nearestNeighborCallnow returnsScore+Distance(vector distances were previously discarded); all non-hybrid behavior is unchanged when the flag is off.How to Test
1. Start Chroma v2
The SEMOSS engine connects on creation, so Chroma must be running before step 2:
Expect version
"1.0.0".2. Create a Chroma vector engine
Set these SMSS properties on a new vector engine, then ingest a small doc set through the catalog's document upload:
TENANT/DB_NAMEare optional (default todefault_tenant/default_database).3. Baseline query (vector-only)
Leave
USE_HYBRID_SEARCHunset orfalse, then run:Each result includes
ScoreandDistance.4. Hybrid query
Add to the engine SMSS and reload the engine:
Optionally tune
HYBRID_VECTOR_WEIGHT(default0.5) andHYBRID_KEYWORD_GATE_THRESHOLD(default0.0). Re-run the same query:Results are re-ranked by weighted RRF (vector + BM25 keyword); a query with a strong keyword match surfaces documents pure vector search ranked lower.
5. (Optional) Metadata filters
Pass
filters/metaFilterson the query and confirm results are restricted to matching metadata (supports$and/$orwith$eq/$in/$ne/$nin/$gt/$gte/$lt/$lte).Notes
falseleaves the existing vector-only behavior untouched.HYBRID_VECTOR_WEIGHTsets the vector weight in RRF; keyword weight is1 - HYBRID_VECTOR_WEIGHT.