文字高亮器Compatible with Milvus 2.6.8+

Milvus 的文字高亮器用可自訂的標籤包裝文字欄位中的匹配詞彙。高亮顯示有助於解釋文件匹配的原因,提高結果的可讀性,並支援搜索和 RAG 應用程式中的豐富渲染。

高亮顯示是作為最終搜尋結果集的後處理步驟來執行的。它不會影響候選人檢索、過濾邏輯、排序或評分。

高亮顯示器提供三個獨立的控制層面:

  • 高亮顯示哪些詞彙

    您可以選擇高亮顯示的詞彙來自哪裡。例如,高亮顯示BM25 全文檢索中使用的搜尋詞彙,或基於文字的篩選表達式(例如TEXT_MATCH 條件)中指定的查詢詞彙。

  • 高亮顯示詞彙的顯示方式

    您可以透過設定在每個匹配詞之前和之後插入的標記,控制匹配詞在高亮輸出中的顯示方式。例如,使用{} 之類的簡單標記或<em></em> 之類的 HTML 標記來進行豐富的呈現。

  • 高亮顯示文字的傳回方式

    您可以控制高亮顯示結果如何以片段形式傳回,包括片段的起始位置、片段的長度以及傳回的片段數量。

以下各節將介紹這些情況。

當您執行 BM25 全文搜尋時,您可以在傳回的結果中高亮顯示搜尋詞彙,以協助說明某個文件符合查詢的原因。若要瞭解有關 BM25 全文搜尋的更多資訊,請參閱全文搜尋

在這種情況下,高亮顯示的詞彙直接來自 BM25 全文搜索中使用的搜索詞彙。高亮顯示器使用這些詞彙在最終結果中注釋匹配的文字。

假設以下內容儲存於文字欄位中:

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

高亮顯示器配置

若要在 BM25 全文搜索中高亮顯示搜尋詞彙,請建立LexicalHighlighter 並啟用 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
)

在此範例中:

  • pre_tagspost_tags 控制高亮文本在輸出中的顯示方式。在此例中,匹配的詞彙由{} 包裝 (例如,{term})。您也可以以清單形式提供多個標籤 (例如:["<b>", "<i>"])。當多個詞彙被高亮顯示時,標籤會依序套用,並依匹配順序旋轉。

  • highlight_search_text=True 告訴 Milvus 使用 BM25 全文檢索中的搜尋詞彙作為高亮詞彙的來源。

一旦建立了 Highlighter 物件,請將其設定套用到您的 BM25 全文檢索請求:

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

高亮輸出

啟用高亮輸出時,Milvus 會在專用的highlight 欄位中傳回高亮文字。預設情況下,高亮輸出會以片段形式從第一個匹配的詞彙開始傳回。

在這個範例中,搜尋詞彙是"BM25" ,所以它會在傳回的結果中高亮顯示:

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

若要控制回傳片段的位置、長度和數量,請參閱以片段方式回傳高亮顯示的文字

過濾中的高亮顯示查詢字詞

除了高亮顯示搜尋詞彙之外,您也可以高亮顯示基於文字的篩選表達式中使用的詞彙。

目前,只有TEXT_MATCH 篩選條件支援查詢詞彙高亮顯示。若要瞭解更多資訊,請參閱文字匹配

在這種情況下,高亮顯示的詞彙來自基於文字的篩選表達式。篩選決定哪些文件匹配,而高亮器會註釋匹配的文字跨度。

假設以下內容儲存於文字欄位中:

This document explains how text filtering works in Milvus.

高亮顯示器配置

若要高亮顯示篩選中使用的查詢字詞,請建立LexicalHighlighter ,並定義與篩選條件對應的highlight_query

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
    }]
)

在此配置中:

  • pre_tagspost_tags 控制高亮文本在輸出中的顯示方式。在這種情況下,匹配的詞彙由{} 包裝(例如,{term} )。您也可以以清單形式提供多個標籤 (例如:["<b>", "<i>"])。當多個詞彙被高亮顯示時,標籤會依序套用,並依匹配順序旋轉。

  • highlight_query 定義應該高亮顯示哪些篩選詞彙。

建立高亮顯示器物件後,請將相同的過濾表達式和高亮顯示器設定套用到您的搜尋請求:

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

高亮顯示輸出

當過濾的查詢字詞高亮被啟用,Milvus 會在一個專用的highlight 欄位回傳高亮的文字。預設情況下,高亮輸出會以片段形式從第一個匹配的詞彙開始傳回。

在這個範例中,第一個匹配的詞彙是"text" ,因此回傳的高亮文字會從該位置開始:

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

若要控制回傳片段的位置、長度和數量,請參閱以片段方式回傳高亮文字

基於片段的高亮輸出

預設情況下,Milvus 會從第一個匹配的詞彙開始,以片段的方式回傳高亮文字。片段相關的設定允許您進一步控制片段的傳回方式,而不改變哪些詞彙被高亮。

假設以下內容儲存於文字欄位中:

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

高亮顯示器設定

要控制高亮顯示片段的形狀,請在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
)

在此配置中

  • fragment_offset 保留第一個反白詞彙之前的前導上下文。

  • fragment_size 限制每個片段包含多少文字。

  • num_of_fragments 控制返回多少片段。

建立高亮物件後,將高亮設定套用至您的搜尋請求:

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

高亮輸出

啟用基於片段的高亮功能後,Milvus 會在highlight 欄位中以片段形式回傳高亮文字:

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

在此輸出中

  • 片段並非完全從{BM25} 開始,因為fragment_offset 已經設定。

  • 只返回一個片段,因為num_of_fragments 是 1。

  • 片段的長度以fragment_size 為上限。

範例

準備工作

使用熒光筆之前,請確保您的集合已正確設定。

下面的範例建立了一個支援 BM25 全文搜尋和TEXT_MATCH 查詢的資料夾,然後插入範例文件。

準備您的資料夾

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

本範例顯示如何在 BM25 全文搜尋中高亮顯示搜尋詞彙。

  • BM25 全文搜索使用"test" 作為搜索詞

  • 高亮度標記使用{} 標籤包圍所有出現的 "test"。

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()

預期輸出

['{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']

範例 2:在篩選中高亮顯示查詢詞彙

本範例展示如何高亮顯示TEXT_MATCH 過濾器匹配的詞彙。

  • BM25 全文搜尋使用"test" 作為查詢字詞

  • queries 參數將"my doc" 加入高亮顯示清單

  • 高亮顯示器將所有匹配的詞彙 ("my","test","doc") 包裝為{}

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()

預期輸出

['{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']

範例 3:以片段形式返回高亮

在這個範例中,查詢會搜尋"Milvus" 並以下列設定傳回高亮片段:

  • fragment_offset 保留第一個高亮區域之前最多 20 個字元為前導上下文 (預設為 0)。

  • fragment_size 限制每個片段約為 60 個字元 (預設為 100)。

  • num_of_fragments 限制每個文字值傳回的片段數量 (預設為 5)。

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()

預期輸出

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']

範例 4:多重查詢高亮顯示

在 BM25 全文搜索中使用多個查詢進行搜索時,每個查詢的結果都會獨立高亮顯示。第一個查詢的結果包含其查詢詞的高亮顯示,第二個查詢的結果包含其查詢詞的高亮顯示,依此類推。每個查詢使用相同的highlighter 設定,但獨立應用。

在下面的範例中:

  • 第一個查詢在其結果集中高亮顯示"test"

  • 第二個查詢在其結果集中高亮顯示"Milvus"

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()

預期輸出

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']

範例 5:自訂 HTML 標籤

您可以使用任何標籤來高亮顯示,例如網頁使用者介面的 HTML 安全標籤。這在瀏覽器中呈現搜尋結果時非常有用。

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()

預期輸出

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