Milvus
Zilliz
Home
  • Guide de l'utilisateur
  • Home
  • Docs
  • Guide de l'utilisateur

  • Recherche

  • Surligneur de texte

Surligneur de texteCompatible with Milvus 2.6.8+

L'outil de mise en évidence de Milvus annote les termes correspondants dans les champs de texte en les entourant de balises personnalisables. Le surlignage permet d'expliquer pourquoi un document correspond, d'améliorer la lisibilité des résultats et de prendre en charge un rendu riche dans les applications de recherche et de RAG.

Le surlignage est exécuté en tant qu'étape de post-traitement sur l'ensemble des résultats finaux de la recherche. Il n'affecte pas la recherche de candidats, la logique de filtrage, le classement ou la notation.

L'outil de mise en évidence offre trois dimensions de contrôle indépendantes :

  • Les termes mis en évidence

    Vous pouvez choisir l'origine des termes mis en évidence. Par exemple, mettre en évidence les termes de recherche utilisés dans la recherche plein texte BM25, ou les termes de la requête spécifiés dans les expressions de filtrage basées sur le texte (telles que les conditions TEXT_MATCH ).

  • Comment les termes en surbrillance sont rendus

    Vous pouvez contrôler la manière dont les termes mis en évidence apparaissent dans la sortie de mise en évidence en configurant les balises insérées avant et après chaque correspondance. Par exemple, utilisez des marqueurs simples comme {} ou des balises HTML comme <em></em> pour un rendu riche.

  • Retour du texte mis en évidence

    Vous pouvez contrôler la manière dont les résultats surlignés sont renvoyés sous forme de fragments, notamment le point de départ des fragments, leur longueur et le nombre de fragments renvoyés.

Les sections suivantes décrivent ces scénarios.

Lorsque vous effectuez une recherche en texte intégral dans BM25, vous pouvez mettre en évidence les termes de recherche dans les résultats renvoyés afin d'expliquer pourquoi un document correspond à la requête. Pour en savoir plus sur la recherche en texte intégral BM25, reportez-vous à la section Recherche en texte intégral.

Dans ce scénario, les termes surlignés proviennent directement des termes de recherche utilisés dans la recherche plein texte BM25. L'outil de mise en évidence utilise ces termes pour annoter le texte correspondant dans le résultat final.

Supposons que le contenu suivant soit stocké dans un champ de texte :

Milvus supports full text search. Use BM25 for keyword relevance. Filters can narrow results.

Configuration de l'outil de surlignage

Pour mettre en évidence les termes de recherche dans la recherche plein texte BM25, créez un site LexicalHighlighter et activez la mise en évidence des termes de recherche pour la recherche plein texte BM25 :

from pymilvus import LexicalHighlighter

highlighter = LexicalHighlighter(
    pre_tags=["{"],              # Tag inserted before each highlighted term
    post_tags=["}"],             # Tag inserted after each highlighted term
    highlight_search_text=True   # Enable search term highlighting for BM25 full text search
)

Dans cet exemple :

  • pre_tags et post_tags contrôlent la manière dont le texte mis en évidence apparaît dans le résultat. Dans ce cas, les termes correspondants sont enveloppés par {} (par exemple, {term}). Vous pouvez également fournir plusieurs balises sous forme de liste (par exemple, ["<b>", "<i>"]). Lorsque plusieurs termes sont mis en évidence, les balises sont appliquées dans l'ordre et tournées selon la séquence de correspondance.

  • highlight_search_text=True indique à Milvus d'utiliser les termes de recherche dans la recherche plein texte BM25 comme source de termes mis en évidence.

Une fois l'objet Highlighter créé, appliquez sa configuration à votre requête de recherche plein texte BM25 :

results = client.search(
    ...,
    data=["BM25"],      # Search term used in BM25 full text search
    highlighter=highlighter # Pass highlighter config here
)

Sortie de la mise en évidence

Lorsque la mise en évidence est activée, Milvus renvoie le texte mis en évidence dans un champ highlight dédié. Par défaut, la sortie surlignée est renvoyée sous la forme d'un fragment commençant par le premier terme trouvé.

Dans cet exemple, le terme recherché est "BM25", il est donc mis en surbrillance dans le résultat renvoyé :

{
    ...,
    "highlight": {
        "text": [
            "{BM25} for keyword relevance. Filters can narrow results."
        ]
    }
}

Pour contrôler la position, la longueur et le nombre de fragments renvoyés, voir Renvoyer le texte mis en évidence sous forme de fragments.

Mise en évidence des termes de recherche dans le filtrage

Outre la mise en surbrillance des termes de recherche, vous pouvez mettre en surbrillance les termes utilisés dans les expressions de filtrage basées sur le texte.

Actuellement, seule la condition de filtrage TEXT_MATCH est prise en charge pour la mise en évidence des termes de la requête. Pour en savoir plus, reportez-vous à la section Correspondance de texte.

Dans ce scénario, les termes mis en évidence proviennent d'expressions de filtrage basées sur le texte. Le filtrage détermine les documents qui correspondent, tandis que l'outil de surlignage annote les parties de texte correspondantes.

Supposons que le contenu suivant soit stocké dans un champ de texte :

This document explains how text filtering works in Milvus.

Configuration de l'article de surbrillance

Pour mettre en évidence les termes de la requête utilisés dans le filtrage, créez un site LexicalHighlighter et définissez un site highlight_query qui correspond à la condition de filtrage :

from pymilvus import LexicalHighlighter

highlighter = LexicalHighlighter(
    pre_tags=["{"],              # Tag inserted before each highlighted term
    post_tags=["}"],             # Tag inserted after each highlighted term
    highlight_query=[{
        "type": "TextMatch",     # Text filtering type
        "field": "text",         # Target text field
        "text": "text filtering" # Terms to highlight
    }]
)

Dans cette configuration :

  • pre_tags et post_tags contrôlent la manière dont le texte mis en évidence apparaît dans la sortie. Dans ce cas, les termes correspondants sont enveloppés par {} (par exemple, {term}). Vous pouvez également fournir plusieurs balises sous forme de liste (par exemple, ["<b>", "<i>"]). Lorsque plusieurs termes sont mis en évidence, les balises sont appliquées dans l'ordre et tournées selon la séquence de correspondance.

  • highlight_query définit les termes de filtrage à mettre en évidence.

Une fois l'objet Highlighter créé, appliquez la même expression de filtrage et la même configuration de mise en évidence à votre demande de recherche :

results = client.search(
    ...,
    filter='TEXT_MATCH(text, "text filtering")',
    highlighter=highlighter # Pass highlighter config here
)

Résultats de la mise en évidence

Lorsque la mise en évidence des termes de la requête est activée pour le filtrage, Milvus renvoie le texte mis en évidence dans un champ highlight dédié. Par défaut, la sortie surlignée est renvoyée sous forme de fragment à partir du premier terme correspondant.

Dans cet exemple, le premier terme correspondant est "text", le texte mis en évidence renvoyé commence donc à cette position :

{
    ...,
    "highlight": {
        "text": [
            "{text} {filtering} works in Milvus."
        ]
    }
}

Pour contrôler la position, la longueur et le nombre de fragments renvoyés, voir Renvoyer le texte surligné sous forme de fragments.

Sortie de la mise en évidence basée sur les fragments

Par défaut, Milvus renvoie le texte mis en évidence sous forme de fragments à partir du premier terme correspondant. Les paramètres relatifs aux fragments vous permettent de contrôler davantage la manière dont les fragments sont renvoyés, sans modifier les termes mis en évidence.

Supposons que le contenu suivant soit stocké dans un champ de texte :

Milvus supports full text search. Use BM25 for keyword relevance. Filters can narrow results.

Configuration de l'outil de mise en évidence

Pour contrôler la forme des fragments mis en évidence, configurez les options relatives aux fragments sur le site LexicalHighlighter:

from pymilvus import LexicalHighlighter

highlighter = LexicalHighlighter(
    pre_tags=["{"],
    post_tags=["}"],
    highlight_search_text=True,
    fragment_offset=5,     # Number of characters to reserve before the first matched term
    fragment_size=60,      # Max. length of each fragment to return
    num_of_fragments=1     # Max. number of fragments to return
)

Dans cette configuration :

  • fragment_offset réserve le contexte avant le premier terme mis en évidence.

  • fragment_size limite la quantité de texte incluse dans chaque fragment.

  • num_of_fragments contrôle le nombre de fragments renvoyés.

Une fois l'objet Highlighter créé, appliquez la configuration du surligneur à votre requête de recherche :

results = client.search(
    ...,
    data=["BM25"],
    highlighter=highlighter # Pass highlighter config here
)

Sortie de la mise en évidence

Lorsque la mise en évidence basée sur les fragments est activée, Milvus renvoie le texte mis en évidence sous forme de fragments dans le champ highlight:

{
    ...,
    "highlight": {
        "text": [
            "Use {BM25} for keyword relevance. Filters can narrow results."
        ]
    }
}

Dans ce résultat :

  • Le fragment ne commence pas exactement à {BM25} car fragment_offset est défini.

  • Un seul fragment est renvoyé car num_of_fragments vaut 1.

  • La longueur du fragment est plafonnée par fragment_size.

Exemples

Préparation

Avant d'utiliser le surligneur, assurez-vous que votre collection est correctement configurée.

L'exemple ci-dessous crée une collection qui prend en charge la recherche en texte intégral BM25 et les requêtes TEXT_MATCH, puis insère des exemples de documents.

Préparez votre collection

from pymilvus import (
    MilvusClient,
    DataType,
    Function,
    FunctionType,
    LexicalHighlighter,
)

client = MilvusClient(uri="http://localhost:19530")
COLLECTION_NAME = "highlighter_demo"

# Clean up existing collection
if client.has_collection(COLLECTION_NAME):
    client.drop_collection(COLLECTION_NAME)

# Define schema
schema = client.create_schema(enable_dynamic_field=False)
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True)
schema.add_field(
    field_name="text",
    datatype=DataType.VARCHAR,
    max_length=2000,
    enable_analyzer=True,  # Required for BM25
    enable_match=True,     # Required for TEXT_MATCH
)
schema.add_field(field_name="sparse_vector", datatype=DataType.SPARSE_FLOAT_VECTOR)

# Add BM25 function
schema.add_function(Function(
    name="text_bm25",
    function_type=FunctionType.BM25,
    input_field_names=["text"],
    output_field_names=["sparse_vector"],
))

# Create index
index_params = client.prepare_index_params()
index_params.add_index(
    field_name="sparse_vector",
    index_type="SPARSE_INVERTED_INDEX",
    metric_type="BM25",
    params={"inverted_index_algo": "DAAT_MAXSCORE", "bm25_k1": 1.2, "bm25_b": 0.75},
)

client.create_collection(collection_name=COLLECTION_NAME, schema=schema, index_params=index_params)

# Insert sample documents
docs = [
    "my first test doc",
    "my second test doc",
    "my first test doc. Milvus is an open-source vector database built for GenAI applications.",
    "my second test doc. Milvus is an open-source vector database that suits AI applications "
    "of every size from running a demo chatbot to building web-scale search.",
]
client.insert(collection_name=COLLECTION_NAME, data=[{"text": t} for t in docs])
print(f"✓ Collection created with {len(docs)} documents\n")

# Helper for search params
SEARCH_PARAMS = {"metric_type": "BM25", "params": {"drop_ratio_search": 0.0}}

# Expected output:
# ✓ Collection created with 4 documents

Cet exemple montre comment mettre en évidence les termes de recherche dans la recherche plein texte BM25.

  • La recherche en texte intégral BM25 utilise "test" comme terme de recherche

  • L'outil de surlignage entoure toutes les occurrences de "test" des balises { et }.

highlighter = LexicalHighlighter(
    pre_tags=["{"],
    post_tags=["}"],
    highlight_search_text=True,  # Highlight BM25 query terms
)

results = client.search(
    collection_name=COLLECTION_NAME,
    data=["test"],
    anns_field="sparse_vector",
    limit=10,
    search_params=SEARCH_PARAMS,
    output_fields=["text"],
    highlighter=highlighter,
)

for hit in results[0]:
    print(f"  {hit.get('highlight', {}).get('text', [])}")
print()

Résultat attendu

['{test} doc']
['{test} doc']
['{test} doc. Milvus is an open-source vector database built for GenAI applications.']
['{test} doc. Milvus is an open-source vector database that suits AI applications of every size from run']

Exemple 2 : Mise en évidence des termes de la requête lors du filtrage

Cet exemple montre comment mettre en évidence les termes correspondant à un filtre TEXT_MATCH.

  • La recherche en texte intégral BM25 utilise "test" comme terme de la requête

  • Le paramètre queries ajoute "my doc" à la liste des termes mis en évidence.

  • L'outil de mise en évidence enveloppe tous les termes correspondants ("my", "test", "doc") avec { et }

highlighter = LexicalHighlighter(
    pre_tags=["{"],
    post_tags=["}"],
    highlight_search_text=True,   # Also highlight BM25 term
    highlight_query=[                     # Additional TEXT_MATCH terms to highlight
        {"type": "TextMatch", "field": "text", "text": "my doc"},
    ],
)

results = client.search(
    collection_name=COLLECTION_NAME,
    data=["test"],
    anns_field="sparse_vector",
    limit=10,
    search_params=SEARCH_PARAMS,
    output_fields=["text"],
    highlighter=highlighter,
)

for hit in results[0]:
    print(f"  {hit.get('highlight', {}).get('text', [])}")
print()

Résultat attendu

['{my} first {test} {doc}']
['{my} second {test} {doc}']
['{my} first {test} {doc}. Milvus is an open-source vector database built for GenAI applications.']
['{my} second {test} {doc}. Milvus is an open-source vector database that suits AI applications of every siz']

Exemple 3 : Renvoi des surlignements sous forme de fragments

Dans cet exemple, la requête recherche "Milvus" et renvoie des fragments de surbrillance selon les paramètres suivants :

  • fragment_offset conserve jusqu'à 20 caractères avant la première portée mise en évidence comme contexte principal (la valeur par défaut est 0).

  • fragment_size limite chaque fragment à environ 60 caractères (100 par défaut).

  • num_of_fragments limite le nombre de fragments renvoyés par valeur de texte (5 par défaut).

highlighter = LexicalHighlighter(
    pre_tags=["{"],
    post_tags=["}"],
    highlight_search_text=True,
    fragment_offset=20,  # Keep 20 chars before match
    fragment_size=60,    # Max ~60 chars per fragment
)

results = client.search(
    collection_name=COLLECTION_NAME,
    data=["Milvus"],
    anns_field="sparse_vector",
    limit=10,
    search_params=SEARCH_PARAMS,
    output_fields=["text"],
    highlighter=highlighter,
)

for i, hit in enumerate(results[0]):
    frags = hit.get('highlight', {}).get('text', [])
    print(f"  Doc {i+1}: {frags}")
print()

Résultats attendus

Doc 1: ['my first test doc. {Milvus} is an open-source vector database ']
Doc 2: ['my second test doc. {Milvus} is an open-source vector database']

Exemple 4 : Mise en évidence de plusieurs requêtes

Lors d'une recherche en texte intégral avec plusieurs requêtes dans BM25, les résultats de chaque requête sont mis en évidence de manière indépendante. Les résultats de la première requête contiennent les surlignages de son terme de recherche, les résultats de la deuxième requête contiennent les surlignages de son terme de recherche, et ainsi de suite. Chaque requête utilise la même configuration highlighter mais l'applique indépendamment.

Dans l'exemple ci-dessous :

  • La première requête met en évidence "test" dans son ensemble de résultats.

  • La deuxième requête met en évidence "Milvus" dans son ensemble de résultats.

highlighter = LexicalHighlighter(
    pre_tags=["{"],
    post_tags=["}"],
    highlight_search_text=True,
)

results = client.search(
    collection_name=COLLECTION_NAME,
    data=["test", "Milvus"],  # Two queries
    anns_field="sparse_vector",
    limit=2,
    search_params=SEARCH_PARAMS,
    output_fields=["text"],
    highlighter=highlighter,
)

for nq_idx, hits in enumerate(results):
    query_term = ["test", "Milvus"][nq_idx]
    print(f"  Query '{query_term}':")
    for hit in hits:
        print(f"    {hit.get('highlight', {}).get('text', [])}")
print()

Résultat attendu

Query 'test':
  ['{test} doc']
  ['{test} doc']
Query 'Milvus':
  ['{Milvus} is an open-source vector database built for GenAI applications.']
  ['{Milvus} is an open-source vector database that suits AI applications of every size from running a dem']

Exemple 5 : Balises HTML personnalisées

Vous pouvez utiliser n'importe quelle balise pour la mise en évidence, comme les balises HTML-safe pour les interfaces utilisateur web. Ceci est utile lors de l'affichage des résultats de recherche dans un navigateur.

highlighter = LexicalHighlighter(
    pre_tags=["<mark>"],
    post_tags=["</mark>"],
    highlight_search_text=True,
)

results = client.search(
    collection_name=COLLECTION_NAME,
    data=["test"],
    anns_field="sparse_vector",
    limit=2,
    search_params=SEARCH_PARAMS,
    output_fields=["text"],
    highlighter=highlighter,
)

for hit in results[0]:
    print(f"  {hit.get('highlight', {}).get('text', [])}")
print()

Résultat attendu

['<mark>test</mark> doc']
['<mark>test</mark> doc']