Marcador de textoCompatible with Milvus 2.6.8+
O Marcador de texto do Milvus anota os termos correspondentes nos campos de texto, envolvendo-os com etiquetas personalizáveis. O realce ajuda a explicar por que um documento corresponde, melhora a legibilidade do resultado e suporta a renderização rica em aplicações de pesquisa e RAG.
O realce é executado como uma etapa de pós-processamento no conjunto final de resultados da pesquisa. Não afecta a recuperação de candidatos, a lógica de filtragem, a classificação ou a pontuação.
O Marcador de destaque fornece três dimensões independentes de controlo:
Que termos são realçados
Pode escolher de onde vêm os termos destacados. Por exemplo, destacar os termos de pesquisa usados na pesquisa de texto completo do BM25 ou os termos de consulta especificados em expressões de filtragem baseadas em texto (como as condições do
TEXT_MATCH).Como os termos destacados são processados
Pode controlar a forma como os termos correspondidos aparecem na saída do realce, configurando as etiquetas inseridas antes e depois de cada correspondência. Por exemplo, use marcadores simples, como
{}, ou tags HTML, como<em></em>, para uma renderização avançada.Como o texto destacado é devolvido
É possível controlar a forma como os resultados realçados são devolvidos como fragmentos, incluindo onde os fragmentos começam, qual o seu comprimento e quantos fragmentos são devolvidos.
As secções seguintes apresentam estes cenários.
Destaque do termo de pesquisa na pesquisa de texto completo do BM25
Ao realizar uma pesquisa de texto completo na BM25, é possível destacar os termos de pesquisa no resultado retornado para ajudar a explicar por que um documento corresponde à consulta. Para saber mais sobre a pesquisa de texto completo do BM25, consulte Pesquisa de texto completo.
Nesse cenário, os termos destacados vêm diretamente dos termos de pesquisa usados na pesquisa de texto completo do BM25. O Marcador de texto utiliza estes termos para anotar o texto correspondente no resultado final.
Suponha que o seguinte conteúdo é armazenado num campo de texto:
Milvus supports full text search. Use BM25 for keyword relevance. Filters can narrow results.
Configuração do Marcador
Para destacar os termos de pesquisa na pesquisa de texto completo do BM25, crie um LexicalHighlighter e active o destaque do termo de pesquisa para a pesquisa de texto completo do 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
)
Neste exemplo:
pre_tagsepost_tagscontrolam a forma como o texto realçado aparece na saída. Neste caso, os termos correspondidos são envolvidos por{}(por exemplo,{term}). Também pode fornecer várias etiquetas como uma lista (por exemplo,["<b>", "<i>"]). Quando vários termos são destacados, as etiquetas são aplicadas por ordem e rodadas pela sequência de correspondência.highlight_search_text=Truediz ao Milvus para utilizar os termos de pesquisa na pesquisa de texto completo BM25 como fonte dos termos destacados.
Uma vez criado o objeto Marcador, aplique a sua configuração ao pedido de pesquisa de texto completo do BM25:
results = client.search(
...,
data=["BM25"], # Search term used in BM25 full text search
highlighter=highlighter # Pass highlighter config here
)
Saída de realce
Quando o realce está ativado, o Milvus devolve o texto realçado num campo dedicado highlight. Por predefinição, a saída destacada é devolvida como um fragmento a partir do primeiro termo correspondido.
Neste exemplo, o termo de pesquisa é "BM25", portanto é destacado no resultado retornado:
{
...,
"highlight": {
"text": [
"{BM25} for keyword relevance. Filters can narrow results."
]
}
}
Para controlar a posição, o comprimento e o número de fragmentos devolvidos, consulte Devolver texto realçado como fragmentos.
Destaque do termo de consulta na filtragem
Para além de realçar os termos de pesquisa, pode realçar os termos utilizados em expressões de filtragem baseadas em texto.
Atualmente, apenas a condição de filtragem TEXT_MATCH é suportada para o realce de termos de consulta. Para saber mais, consulte Correspondência de texto.
Nesse cenário, os termos destacados vêm de expressões de filtragem baseadas em texto. A filtragem determina quais documentos correspondem, enquanto o Marcador de texto anota os intervalos de texto correspondentes.
Suponha que o conteúdo a seguir seja armazenado em um campo de texto:
This document explains how text filtering works in Milvus.
Configuração do Marcador de texto
Para realçar os termos de consulta utilizados na filtragem, crie um LexicalHighlighter e defina um highlight_query que corresponda à condição de filtragem:
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
}]
)
Nesta configuração:
pre_tagsepost_tagscontrolam como o texto realçado aparece na saída. Neste caso, os termos correspondentes são envolvidos por{}(por exemplo,{term}). Você também pode fornecer várias marcas como uma lista (por exemplo,["<b>", "<i>"]). Quando vários termos são destacados, as etiquetas são aplicadas por ordem e rodadas pela sequência de correspondência.highlight_querydefine quais termos de filtragem devem ser destacados.
Uma vez criado o objeto Marcador, aplique a mesma expressão de filtragem e a configuração do marcador ao seu pedido de pesquisa:
results = client.search(
...,
filter='TEXT_MATCH(text, "text filtering")',
highlighter=highlighter # Pass highlighter config here
)
Destacando a saída
Quando o realce do termo de consulta está ativado para filtragem, o Milvus devolve o texto realçado num campo dedicado highlight. Por predefinição, o resultado destacado é devolvido como um fragmento a partir do primeiro termo correspondido.
Neste exemplo, o primeiro termo correspondido é "text", pelo que o texto realçado devolvido começa a partir dessa posição:
{
...,
"highlight": {
"text": [
"{text} {filtering} works in Milvus."
]
}
}
Para controlar a posição, o comprimento e o número de fragmentos devolvidos, consulte Devolver texto realçado como fragmentos.
Saída do realce baseado em fragmentos
Por defeito, o Milvus devolve o texto realçado como fragmentos a partir do primeiro termo correspondido. As definições relacionadas com fragmentos permitem-lhe controlar melhor a forma como os fragmentos são devolvidos, sem alterar os termos realçados.
Suponha que o seguinte conteúdo é armazenado num campo de texto:
Milvus supports full text search. Use BM25 for keyword relevance. Filters can narrow results.
Configuração do marcador
Para controlar a forma dos fragmentos destacados, configure as opções relacionadas com os fragmentos em 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
)
Nesta configuração:
fragment_offsetreserva o contexto principal antes do primeiro termo destacado.fragment_sizelimita a quantidade de texto incluída em cada fragmento.num_of_fragmentscontrola quantos fragmentos são devolvidos.
Uma vez criado o objeto Marcador, aplique a configuração do marcador ao seu pedido de pesquisa:
results = client.search(
...,
data=["BM25"],
highlighter=highlighter # Pass highlighter config here
)
Saída de realce
Com o realce baseado em fragmentos ativado, o Milvus devolve o texto realçado como fragmentos no campo highlight:
{
...,
"highlight": {
"text": [
"Use {BM25} for keyword relevance. Filters can narrow results."
]
}
}
Nesta saída:
O fragmento não começa exatamente em
{BM25}porquefragment_offsetestá definido.Apenas um fragmento é devolvido porque
num_of_fragmentsé 1.O comprimento do fragmento é limitado por
fragment_size.
Exemplos
Preparação
Antes de utilizar o marcador, certifique-se de que a sua coleção está corretamente configurada.
O exemplo abaixo cria uma coleção que suporta a pesquisa de texto completo BM25 e as consultas TEXT_MATCH e, em seguida, insere documentos de amostra.
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
Exemplo 1: Destacar termos de pesquisa na pesquisa de texto completo BM25
Este exemplo mostra como destacar termos de pesquisa na pesquisa de texto completo BM25.
A pesquisa de texto completo BM25 utiliza
"test"como termo de pesquisaO destacador envolve todas as ocorrências de "test" com as etiquetas
{e}
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']
Exemplo 2: Destacar termos de consulta na filtragem
Este exemplo mostra como destacar os termos correspondentes a um filtro TEXT_MATCH.
A pesquisa de texto completo BM25 usa
"test"como termo de consultaO parâmetro
queriesadiciona"my doc"à lista de destaqueO realçador envolve todos os termos correspondentes (
"my","test","doc") com{e}
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']
Exemplo 3: Devolver destaques como fragmentos
Neste exemplo, a consulta procura por "Milvus" e retorna fragmentos de destaque nas seguintes configurações:
fragment_offsetmantém até 20 caracteres antes do primeiro intervalo destacado como contexto inicial (o padrão é 0).fragment_sizelimita cada fragmento a aproximadamente 60 caracteres (o padrão é 100).num_of_fragmentslimita o número de fragmentos devolvidos por valor de texto (a predefinição é 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']
Exemplo 4: Destaque de várias consultas
Ao pesquisar com várias consultas na pesquisa de texto completo do BM25, os resultados de cada consulta são destacados de forma independente. Os resultados da primeira consulta contêm destaques para o seu termo de pesquisa, e os resultados da segunda consulta contêm destaques para o seu termo de pesquisa, e assim por diante. Cada consulta utiliza a mesma configuração highlighter mas aplica-a de forma independente.
No exemplo abaixo:
A primeira consulta destaca
"test"no seu conjunto de resultadosA segunda consulta destaca
"Milvus"no seu conjunto de resultados
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']
Exemplo 5: Etiquetas HTML personalizadas
Pode utilizar quaisquer etiquetas para realçar, tais como etiquetas HTML-safe para UIs da Web. Isto é útil ao renderizar resultados de pesquisa num browser.
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']