Retrieval

Retrieval finds the chunks that are relevant to a query. You query the Mistral Search Index directly, through one of two methods:

MethodUse it for
searchSimple queries: send a query and get the best-matching chunks, with vector or hybrid search.
retrieveCustom retrieval logic: choose and combine retrievers, match custom fields, weight the fusion, and filter on your fields.

Start with search. When you need to filter results or control how they're ranked, switch to retrieve.

Both methods rank chunks across the whole index. To read a document in order from a hit, for example the chunks around it, use document navigation.

The examples on this page share this setup:

from mistralai.search.toolkit.embedding import MistralEmbedder
from mistralai.search.toolkit.mistral_search_index import MistralSearchIndexService

index = await MistralSearchIndexService().get_search_index("my_collection")
embedder = MistralEmbedder(model_name="mistral-embed")

search takes a VectorSearchQuery and returns a list of SearchResult objects, best match first. Embed the query with the same model that the index uses:

from mistralai.search.toolkit.search import VectorSearchQuery

question = "How do I rotate an API key?"
embedding = await embedder.embed_query(question)

results = await index.search(
    VectorSearchQuery(query=question, embedding=embedding, top_k=10)
)

for result in results:
    print(f"{result.score:.3f}  {result.chunk.source_id}  {result.chunk.content[:80]}")

The fields that you set on the query determine the search strategy:

  • Vector search: set only embedding. The index returns the chunks whose embeddings are closest to the query's.
  • Hybrid search: set both query and embedding. The index also matches the query's keywords on content and fuses both rankings with reciprocal rank fusion. Exact terms, such as names or error codes, then count alongside meaning.

VectorSearchQuery also takes the following fields:

FieldTypeDefaultPurpose
top_kint10Number of results, at most 100
exclude_idsset[str]emptyChunk IDs to leave out
exclude_source_idsset[str]emptySource documents to leave out
approximate_optionsApproximateQueryOptionsdefaultmax_candidates for the approximate nearest-neighbor search

Every hit includes its custom fields alongside the chunk. To filter on those fields, match keywords on a custom field, or weight the fusion, use retrieve.

Retrieve

Retrieve

retrieve takes a retriever: a description of the query that the index runs as is. You compose it yourself, so you can express retrieval logic that search doesn't cover. Import the retrievers from mistralai.search.toolkit.mistral_search_index.retriever:

RetrieverPurpose
NearestNeighbourRetrieverVector search. With a Mistral embedding model, pass query and the index embeds it.
KeywordRetrieverKeyword search on content, or on any indexed text custom field through field.
RRFRetrieverHybrid search: fuses the rankings of its child retrievers with reciprocal rank fusion.

For all the options of each retriever, see Retrievers.

Filter the results

To keep only the chunks whose fields match, such as a category, a publication year, or a list of source documents, add a filter to any retriever. The index applies the filter as part of the search, so top_k only counts chunks that pass the filter. On an RRFRetriever, the filter applies to every child.

The following query matches the question against the chunk text and against a custom title field, with twice the weight on title. It fuses these rankings with vector search and keeps only financial and legal documents published since 2022:

from mistralai.search.toolkit.mistral_search_index.retriever import (
    And,
    In,
    KeywordRetriever,
    NearestNeighbourRetriever,
    Range,
    RRFRetriever,
)

question = "termination clauses"

results = await index.retrieve(
    RRFRetriever(
        top_k=10,
        filter=And(matches=[
            In(field="category", values=["financial", "legal"]),
            Range(field="published_year", gte=2022),
        ]),
        retrievers=[
            KeywordRetriever(query=question, top_k=20),
            KeywordRetriever(query=question, field="title", top_k=20),
            NearestNeighbourRetriever(query=question, top_k=20),
        ],
        weights=[1.0, 2.0, 1.0],
    )
)

For the available conditions, how to combine them, and the fields that you can filter on, see Filters.

Results

Results

Both methods return SearchResult objects. Each chunk carries the chunk's content, its document-scope and chunk-scope custom fields, and its identity (id, source_id, locator). Results don't include embeddings.

A higher score means a better match. Its scale depends on the retriever: 1 - distance for cosine vector search, a keyword relevance score for KeywordRetriever, and the fused score for RRFRetriever and hybrid search. For details, see Results.