Filtres

Un filtre ne conserve que les fragments dont les champs correspondent à un ensemble de conditions : documents d'une catégorie donnée, publiés après une certaine date, ou issus d'une liste de sources. Définissez-le sur n'importe quel retriever que vous passez à retrieve. L'index applique le filtre au moment de la recherche, si bien que top_k ne compte que les fragments qui passent le filtre.

Importez les filtres depuis le même module que les retrievers, mistralai.search.toolkit.mistral_search_index.retriever :

from mistralai.search.toolkit.mistral_search_index.retriever import (
    Equal,
    NearestNeighbourRetriever,
)

results = await index.retrieve(
    NearestNeighbourRetriever(
        query="termination clauses",
        top_k=10,
        filter=Equal(field="category", value="legal"),
    )
)
Champs filtrables

Champs filtrables

Vous pouvez filtrer sur les champs suivants :

  • Champs personnalisés de type scalaire : text, keyword, int, long, float et timestamp. Déclarez-les dans votre schéma. Pour plus d'informations, consultez Déclarer une collection.
  • Champs système tels que id et source_id.

Vous ne pouvez pas filtrer sur les champs de type array, json ou bool. Pour connaître le type de chaque champ, voir Champs personnalisés.

Faut-il indexer le champ ?

Les filtres fonctionnent sur tous les champs filtrables, qu'ils soient indexés ou non. L'indexation d'un champ avec MistralSearchIndexField(indexed=True) ne fait qu'accélérer le filtrage sur ce champ. Par défaut, les champs text et keyword sont indexés, et les champs numériques et timestamp ne le sont pas.

Il est rarement nécessaire d'indexer un champ pour le filtrage. Indexez un champ lorsque la plupart de vos requêtes filtrent sur ce champ, ou lorsqu'un filtre ne conserve qu'une petite fraction de l'index. Dans ce cas, l'index peut trouver les fragments correspondants plus rapidement. Vous pouvez activer indexed plus tard avec update_index.

Conditions

Conditions

Une condition compare un champ à une ou plusieurs valeurs :

ConditionCorrespondance quandValeurs
Equal(field, value)Le champ est égal à valuestr, int, float ou datetime
In(field, values)Le champ est égal à l'une des valuesUne liste de str, int, float ou datetime
Range(field, gt=, gte=, lt=, lte=)Le champ est compris entre les bornesint, float ou datetime

Un Range nécessite au moins une borne. Vous ne pouvez pas définir à la fois gt et gte, ni à la fois lt et lte. La borne inférieure doit être plus petite que la borne supérieure, et les deux bornes doivent être du même type, bien que vous puissiez mélanger int et float.

from datetime import UTC, datetime, timedelta

from mistralai.search.toolkit.mistral_search_index.retriever import Equal, In, Range

Equal(field="category", value="legal")
In(field="source_id", values=["s3://docs/api-keys.md", "s3://docs/members.md"])
Range(field="published_year", gte=2022, lt=2025)
Range(field="ingested_at", gte=datetime.now(UTC) - timedelta(days=7))
Combiner des conditions

Combiner des conditions

Pour combiner des conditions, utilisez And, Or et Not. Vous pouvez les imbriquer :

from mistralai.search.toolkit.mistral_search_index.retriever import And, Equal, In, Not, Or, Range

filter = And(matches=[
    Or(matches=[
        Equal(field="category", value="legal"),
        Range(field="published_year", gte=2022),
    ]),
    Not(match=In(field="source_id", values=["s3://docs/draft.md"])),
])

Pour exclure les résultats que vous avez déjà vus, par exemple dans une requête de suivi, enveloppez une condition In sur source_id ou id dans un Not.

Filtres dans la récupération hybride

Filtres dans la récupération hybride

Un filtre sur un RRFRetriever s'applique à tous les retrievers enfants. Un enfant peut également porter son propre filtre. L'index le combine avec le filtre parent à l'aide d'un AND, de sorte que le filtre enfant ne restreint que cet enfant :

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

question = "termination clauses"

results = await index.retrieve(
    RRFRetriever(
        top_k=10,
        filter=Range(field="published_year", gte=2022),
        retrievers=[
            KeywordRetriever(query=question, top_k=20, filter=Equal(field="category", value="legal")),
            NearestNeighbourRetriever(query=question, top_k=20),
        ],
    )
)

Dans cet exemple, le retriever enfant keyword ne renvoie que des documents juridiques, et le retriever enfant vectoriel recherche dans toutes les catégories. Les deux enfants ne prennent en compte que les documents publiés depuis 2022.

Voir aussi

Voir aussi