文字高亮器Compatible with Milvus 2.6.8+
Milvus 的文字高亮器用可自訂的標籤包裝文字欄位中的匹配詞彙。高亮顯示有助於解釋文件匹配的原因,提高結果的可讀性,並支援搜索和 RAG 應用程式中的豐富渲染。
高亮顯示是作為最終搜尋結果集的後處理步驟來執行的。它不會影響候選人檢索、過濾邏輯、排序或評分。
高亮顯示器提供三個獨立的控制層面:
高亮顯示哪些詞彙
您可以選擇高亮顯示的詞彙來自哪裡。例如,高亮顯示BM25 全文檢索中使用的搜尋詞彙,或基於文字的篩選表達式(例如
TEXT_MATCH條件)中指定的查詢詞彙。高亮顯示詞彙的顯示方式
您可以透過設定在每個匹配詞之前和之後插入的標記,控制匹配詞在高亮輸出中的顯示方式。例如,使用
{}之類的簡單標記或<em></em>之類的 HTML 標記來進行豐富的呈現。高亮顯示文字的傳回方式
您可以控制高亮顯示結果如何以片段形式傳回,包括片段的起始位置、片段的長度以及傳回的片段數量。
以下各節將介紹這些情況。
在 BM25 全文搜索中高亮顯示搜索詞
當您執行 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_tags和post_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_tags和post_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
範例 1:在 BM25 全文檢索中高亮顯示檢索字詞
本範例顯示如何在 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']