Milvus
Zilliz
홈페이지
  • 사용자 가이드
  • Home
  • Docs
  • 사용자 가이드

  • 검색

  • 텍스트 형광펜

텍스트 하이라이터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 는 밀버스에게 BM25 전체 텍스트 검색의 검색어를 강조 표시된 용어의 소스로 사용하도록 지시합니다.

하이라이터 개체가 생성되면 해당 구성을 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."
        ]
    }
}

이 출력에서:

  • fragment_offset 이 설정되어 있기 때문에 조각이 {BM25} 에서 정확히 시작되지 않습니다.

  • 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 태그

웹 UI용 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']