deepset-ai / deepset-ai/haystack-core-integrations
Filter document from score_threshold after search in QdrantDocumentStore
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 203
- Forks
- 332
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 80
Description
Is your feature request related to a problem? Please describe.
While working with the QdrantHybridRetriever I found out that the score_threshold parameter can be a little tricky to understand and seems like that it is used only during the search of the sparse vectors as shown here in the QdrantDocumentStore module:
...
sparse_request = rest.SearchRequest(
vector=rest.NamedSparseVector(
name=SPARSE_VECTORS_NAME,
vector=rest.SparseVector(
indices=query_sparse_embedding.indices,
values=query_sparse_embedding.values,
),
),
filter=qdrant_filters,
limit=top_k,
with_payload=True,
with_vector=return_embedding,
score_threshold=score_threshold,
)
dense_request = rest.SearchRequest(
vector=rest.NamedVector(
name=DENSE_VECTORS_NAME,
vector=query_embedding,
),
filter=qdrant_filters,
limit=top_k,
with_payload=True,
with_vector=return_embedding,
)
...
The score that is returned from the requests is not normalized, so that make more difficult to set a threshold score.
Describe the solution you'd like
A simple solution to this problem can be implemented in one of these ways:
- Solution A:
- Remove the
score_thresholdfrom the sparse vector search - Add an optional parameter to the
reciprocal_rank_fusionfunction so that it can optionally filter all the points that have a score lower than the threshold
- Solution B:
- Remove the
score_thresholdfrom the sparse vector search - Add a condition on the point score to the following list comprehension:
results = [convert_qdrant_point_to_haystack_document(point, use_sparse_embeddings=True) for point in points if point.score >= score_threshold]
Describe alternatives you've considered
Another alternative, is to implement a component that filters out the document based on the score given from the retriever like this:
@component
class RetrieverDocumentFilter:
@component.output_types(documents=List[Document])
def run(self, documents: List[Document], score_threshold: float):
return {"documents": [d for d in documents if d.score >= score_threshold]}
Although is not a bad solution, I think it should be a cool thing to be able to perform the filtering directly on the retriever component
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Locate the QdrantDocumentStore module and the reciprocal_rank_fusion entry point, then trace how score_threshold reaches the sparse and dense SearchRequest calls. Choose one filtering point described in the issue, ensure the threshold consistently applies to returned documents, and verify the resulting behavior across hybrid retrieval.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- databases, machine-learning
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100