Lexical Highlighter
Zilliz Cloud の Highlighter は、テキストフィールド内の一致した語句をカスタマイズ可能なタグで囲むことで注釈を付けます。ハイライトは、ドキュメントが一致する理由を説明し、結果の可読性を高め、検索や RAG アプリケーションでのリッチなレンダリングをサポートします。
ハイライトは、最終的な検索結果セットに対する後処理ステップとして実行されます。候補の取得、フィルタリングロジック、ランキング、スコアリングには影響しません。
Highlighter では、次の 3 つの独立した制御項目を提供します。
-
ハイライトする語句
ハイライトする語句の取得元を選択できます。たとえば、BM25 全文検索で使用される検索語句、またはテキストベースのフィルタリング式(
TEXT_MATCH条件など)で指定されたクエリ語句をハイライトします。 -
ハイライトする語句のレンダリング方法
各一致の前後に挿入するタグを設定することで、一致した語句がハイライト出力でどのように表示されるかを制御できます。たとえば、
{}のような単純なマーカーや、<em></em>のような HTML タグを使用してリッチにレンダリングできます。 -
ハイライトされたテキストの返却方法
フラグメントとして返されるハイライト結果について、フラグメントの開始位置、長さ、返される数を制御できます。
以降のセクションでは、これらのシナリオについて説明します。
BM25 全文検索での検索語句のハイライト
BM25 全文検索を実行する際に、返された結果内の検索語句をハイライトして、ドキュメントがクエリに一致した理由を説明できます。BM25 全文検索の詳細は、全文検索 を参照してください。
このシナリオでは、ハイライトされる語句は BM25 全文検索で使用される検索語句から直接取得されます。Highlighter はこれらの語句を使用して、最終結果内の一致したテキストに注釈を付けます。
テキストフィールドに次の内容が格納されているとします。
Milvus supports full text search. Use BM25 for keyword relevance. Filters can narrow results.
Highlighter 設定
BM25 全文検索で検索語句をハイライトするには、LexicalHighlighter を作成し、BM25 全文検索の検索語句ハイライトを有効にします。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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
)
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import java.util.*;
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.build();
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true);
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
};
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
var highlighter = new SearchParameters
{
HighlightType = HighlightType.Lexical,
Highlighter =
{
["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
}
};
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
この例では:
-
pre_tagsとpost_tagsは、ハイライトされたテキストが出力でどのように表示されるかを制御します。この場合、一致した語句は{}で囲まれます(例:{term})。複数のタグをリストとして指定することもできます(例:["<b>", "<i>"])。複数の語句がハイライトされる場合、タグは順番に適用され、一致した順序に従ってローテーションされます。 -
highlight_search_text=Trueは、BM25 全文検索の検索語句をハイライト対象語句のソースとして使用するよう Zilliz Cloud に指示します。
Highlighter オブジェクトを作成したら、その設定を BM25 全文検索リクエストに適用します。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
results = client.search(
collection_name="highlighter_demo",
data=["BM25"], # Search term used in BM25 full text search
search_params={"metric_type": "BM25"},
highlighter=highlighter # Pass highlighter config here
)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName("highlighter_demo")
.data(Collections.singletonList(new EmbeddedText("BM25")))
.annsField("sparse_vector")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true);
let res = client
.search(
SearchRequest::builder()
.collection_name("highlighter_demo")
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["BM25".to_string()]))
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
auto request = milvus::SearchRequest()
.WithCollectionName("highlighter_demo")
.WithAnnsField("sparse_vector")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("BM25")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
};
const res = await client.search({
collection_name: "highlighter_demo",
data: ["BM25"],
anns_field: "sparse_vector",
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
var highlighter = new SearchParameters
{
OutputFields = { "text" },
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]",
["post_tags"] = "[\"}\"]",
["highlight_search_text"] = "true"
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = "highlighter_demo",
VectorFieldName = "sparse_vector",
Texts = new[] { "BM25" }, // Search term used in BM25 full text search
MetricType = MetricType.Bm25,
Limit = 10,
Parameters = highlighter // Pass highlighter config here
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
ハイライト出力
ハイライトが有効になると、Zilliz Cloud は専用の highlight フィールドにハイライトされたテキストを返します。デフォルトでは、ハイライト出力は最初に一致した語句から始まるフラグメントとして返されます。
この例では、検索語句は "BM25" であるため、返された結果内で次のようにハイライトされます。
{
...,
"highlight": {
"text": [
"{BM25} for keyword relevance. Filters can narrow results."
]
}
}
返されるフラグメントの位置、長さ、数を制御するには、ハイライトされたテキストをフラグメントとして返す を参照してください。
フィルタリングでのクエリ語句のハイライト
検索語句のハイライトに加えて、テキストベースのフィルタリング式で使用される語句をハイライトできます。
現在、クエリ語句のハイライトでは TEXT_MATCH フィルタリング条件のみがサポートされています。詳細は、テキストマッチ を参照してください。
このシナリオでは、ハイライトされる語句はテキストベースのフィルタリング式から取得されます。フィルタリングはどのドキュメントが一致するかを決定し、Highlighter は一致したテキストの範囲に注釈を付けます。
テキストフィールドに次の内容が格納されているとします。
This document explains how text filtering works in Milvus.
Highlighter 設定
フィルタリングで使用されるクエリ語句をハイライトするには、LexicalHighlighter を作成し、フィルタリング条件に対応する highlight_query を定義します。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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
}]
)
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import java.util.*;
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.addHighlightQuery(new LexicalHighlighter.HighlightQuery("TextMatch", "text", "text filtering"))
.build();
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.add_highlight_query(HighlightQuery::new()
.query_type("TextMatch")
.field("text")
.text("text filtering"));
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->AddHighlightQuery("TextMatch", "text", "text filtering");
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_query: [
{ type: "TextMatch", field: "text", text: "text filtering" },
],
};
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
var highlighter = new SearchParameters
{
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]", // Tag inserted before each highlighted term
["post_tags"] = "[\"}\"]", // Tag inserted after each highlighted term
["highlight_query"] = "[{\"type\":\"TextMatch\",\"field\":\"text\",\"text\":\"text filtering\"}]"
}
};
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
この設定では:
-
pre_tagsとpost_tagsは、ハイライトされたテキストが出力でどのように表示されるかを制御します。この場合、一致した語句は{}で囲まれます(例:{term})。複数のタグをリストとして指定することもできます(例:["<b>", "<i>"])。複数の語句がハイライトされる場合、タグは順番に適用され、一致した順序に従ってローテーションされます。 -
highlight_queryは、ハイライトするフィルタリング語句を定義します。
Highlighter オブジェクトを作成したら、同じフィルタリング式と Highlighter 設定を検索リクエストに適用します。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
results = client.search(
collection_name="highlighter_demo",
data=["BM25"],
filter='TEXT_MATCH(text, "text filtering")',
search_params={"metric_type": "BM25"},
highlighter=highlighter # Pass highlighter config here
)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.addHighlightQuery(new LexicalHighlighter.HighlightQuery("TextMatch", "text", "text filtering"))
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName("highlighter_demo")
.data(Collections.singletonList(new EmbeddedText("BM25")))
.annsField("sparse_vector")
.filter("TEXT_MATCH(text, \"text filtering\")")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.add_highlight_query(HighlightQuery::new()
.query_type("TextMatch")
.field("text")
.text("text filtering"));
let res = client
.search(
SearchRequest::builder()
.collection_name("highlighter_demo")
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["BM25".to_string()]))
.filter(r#"TEXT_MATCH(text, "text filtering")"#)
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->AddHighlightQuery("TextMatch", "text", "text filtering");
auto request = milvus::SearchRequest()
.WithCollectionName("highlighter_demo")
.WithAnnsField("sparse_vector")
.WithFilter(R"(TEXT_MATCH(text, "text filtering"))")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("BM25")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_query: [
{ type: "TextMatch", field: "text", text: "text filtering" },
],
};
const res = await client.search({
collection_name: "highlighter_demo",
data: ["BM25"],
anns_field: "sparse_vector",
filter: 'TEXT_MATCH(text, "text filtering")',
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
var highlighter = new SearchParameters
{
OutputFields = { "text" },
Expression = "TEXT_MATCH(text, \"text filtering\")",
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]",
["post_tags"] = "[\"}\"]",
["highlight_query"] = "[{\"type\":\"TextMatch\",\"field\":\"text\",\"text\":\"text filtering\"}]"
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = "highlighter_demo",
VectorFieldName = "sparse_vector",
Texts = new[] { "BM25" },
MetricType = MetricType.Bm25,
Limit = 10,
Parameters = highlighter
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
ハイライト出力
フィルタリングでクエリ語句のハイライトが有効な場合、Zilliz Cloud は専用の highlight フィールドにハイライトされたテキストを返します。デフォルトでは、ハイライト出力は最初に一致した語句から始まるフラグメントとして返されます。
この例では、最初に一致した語句は "text" であるため、返されるハイライトされたテキストはその位置から始まります。
{
...,
"highlight": {
"text": [
"{text} {filtering} works in Milvus."
]
}
}
返されるフラグメントの位置、長さ、数を制御するには、ハイライトされたテキストをフラグメントとして返す を参照してください。
フラグメントベースのハイライト出力
デフォルトでは、Zilliz Cloud は最初に一致した語句から始まるフラグメントとしてハイライトされたテキストを返します。フラグメント関連の設定を使用すると、ハイライトする語句を変更せずに、フラグメントの返却方法をさらに制御できます。
テキストフィールドに次の内容が格納されているとします。
Milvus supports full text search. Use BM25 for keyword relevance. Filters can narrow results.
Highlighter 設定
ハイライトされたフラグメントの形状を制御するには、LexicalHighlighter でフラグメント関連のオプションを設定します。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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
)
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import java.util.*;
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.fragmentOffset(5)
.fragmentSize(60)
.numOfFragments(1)
.build();
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true)
.fragment_offset(5)
.fragment_size(60)
.num_of_fragments(1);
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
highlighter->WithFragmentOffset(5);
highlighter->WithFragmentSize(60);
highlighter->WithNumOfFragments(1);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
fragment_offset: 5,
fragment_size: 60,
num_of_fragments: 1,
};
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
var highlighter = new SearchParameters
{
HighlightType = HighlightType.Lexical,
Highlighter =
{
["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
}
};
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
この設定では:
-
fragment_offsetは、最初にハイライトされた語句の前に先行コンテキストを確保します。 -
fragment_sizeは、各フラグメントに含めるテキスト量を制限します。 -
num_of_fragmentsは、返されるフラグメントの数を制御します。
Highlighter オブジェクトを作成したら、Highlighter 設定を検索リクエストに適用します。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
results = client.search(
collection_name="highlighter_demo",
data=["BM25"],
search_params={"metric_type": "BM25"},
highlighter=highlighter # Pass highlighter config here
)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName("highlighter_demo")
.data(Collections.singletonList(new EmbeddedText("BM25")))
.annsField("sparse_vector")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true);
let res = client
.search(
SearchRequest::builder()
.collection_name("highlighter_demo")
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["BM25".to_string()]))
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
auto request = milvus::SearchRequest()
.WithCollectionName("highlighter_demo")
.WithAnnsField("sparse_vector")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("BM25")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
};
const res = await client.search({
collection_name: "highlighter_demo",
data: ["BM25"],
anns_field: "sparse_vector",
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
var highlighter = new SearchParameters
{
OutputFields = { "text" },
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]",
["post_tags"] = "[\"}\"]",
["highlight_search_text"] = "true",
["fragment_offset"] = "5",
["fragment_size"] = "60",
["num_of_fragments"] = "1"
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = "highlighter_demo",
VectorFieldName = "sparse_vector",
Texts = new[] { "BM25" },
MetricType = MetricType.Bm25,
Limit = 10,
Parameters = highlighter
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
ハイライト出力
フラグメントベースのハイライトが有効な場合、Zilliz Cloud は highlight フィールドにハイライトされたテキストをフラグメントとして返します。
{
...,
"highlight": {
"text": [
"Use {BM25} for keyword relevance. Filters can narrow results."
]
}
}
この出力では:
-
fragment_offsetが設定されているため、フラグメントは正確に{BM25}から始まりません。 -
num_of_fragmentsが 1 であるため、フラグメントは 1 つだけ返されます。 -
フラグメントの長さは
fragment_sizeによって上限が設定されます。
例
事前準備
Highlighter を使用する前に、コレクションが適切に設定されていることを確認してください。
次の例では、BM25 全文検索と TEXT_MATCH クエリをサポートするコレクションを作成し、サンプルドキュメントを挿入します。
コレクションを準備する
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
from pymilvus import (
MilvusClient,
DataType,
Function,
FunctionType,
LexicalHighlighter,
)
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
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
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq.Function;
import io.milvus.v2.service.collection.request.DropCollectionReq;
import io.milvus.v2.service.collection.request.HasCollectionReq;
import io.milvus.v2.service.vector.request.InsertReq;
import com.google.gson.JsonObject;
import java.util.*;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
String COLLECTION_NAME = "highlighter_demo";
if (client.hasCollection(HasCollectionReq.builder().collectionName(COLLECTION_NAME).build())) {
client.dropCollection(DropCollectionReq.builder().collectionName(COLLECTION_NAME).build());
}
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.autoID(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("text")
.dataType(DataType.VarChar)
.maxLength(2000)
.enableAnalyzer(true)
.enableMatch(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("sparse_vector")
.dataType(DataType.SparseFloatVector)
.build());
schema.addFunction(Function.builder()
.functionType(FunctionType.BM25)
.name("text_bm25")
.inputFieldNames(Collections.singletonList("text"))
.outputFieldNames(Collections.singletonList("sparse_vector"))
.build());
IndexParam indexParam = IndexParam.builder()
.fieldName("sparse_vector")
.indexType(IndexParam.IndexType.SPARSE_INVERTED_INDEX)
.metricType(IndexParam.MetricType.BM25)
.build();
client.createCollection(CreateCollectionReq.builder()
.collectionName(COLLECTION_NAME)
.collectionSchema(schema)
.indexParams(Collections.singletonList(indexParam))
.build());
List<String> docs = Arrays.asList(
"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."
);
List<JsonObject> rows = new ArrayList<>();
for (String doc : docs) {
JsonObject row = new JsonObject();
row.addProperty("text", doc);
rows.add(row);
}
client.insert(InsertReq.builder().collectionName(COLLECTION_NAME).data(rows).build());
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
use std::collections::HashMap;
let client = ClientV2::new(&ConnectConfig::new().uri("YOUR_CLUSTER_ENDPOINT")).await?;
const COLLECTION_NAME: &str = "highlighter_demo";
if client.has_collection(HasCollectionRequest::builder().collection_name(COLLECTION_NAME).build()?).await?.exists() {
client.drop_collection(DropCollectionRequest::builder().collection_name(COLLECTION_NAME).build()?).await?;
}
let schema = CollectionSchema::new()
.add_field(FieldSchema::new().name("id").data_type(DataType::Int64).primary_key(true).auto_id(true))
.add_field(FieldSchema::new().name("text").data_type(DataType::VarChar).max_length(2000).enable_analyzer(true).enable_match(true))
.add_field(FieldSchema::new().name("sparse_vector").data_type(DataType::SparseFloatVector))
.add_function(Function::new().name("text_bm25").function_type(FunctionType::Bm25).input_fields(["text"]).output_fields(["sparse_vector"]));
let index_param = IndexParam::new()
.field_name("sparse_vector")
.index_type(IndexType::SparseInvertedIndex)
.metric_type(MetricType::Bm25)
.extra_params(HashMap::from([
("inverted_index_algo".into(), "DAAT_MAXSCORE".into()),
("bm25_k1".into(), "1.2".into()),
("bm25_b".into(), "0.75".into()),
]));
client
.create_collection(
CreateCollectionRequest::builder()
.collection_name(COLLECTION_NAME)
.schema(schema)
.index_param(index_param)
.build()?,
)
.await?;
// insert + SEARCH_PARAMS (see full text search guide)
#include "milvus/MilvusClientV2.h"
#include <iostream>
auto client = milvus::MilvusClientV2::Create();
auto status = client->Connect(milvus::ConnectParam("YOUR_CLUSTER_ENDPOINT"));
const std::string COLLECTION_NAME = "highlighter_demo";
if (client->HasCollection(COLLECTION_NAME)) {
client->DropCollection(COLLECTION_NAME);
}
milvus::CreateCollectionRequest request;
request.WithCollectionName(COLLECTION_NAME);
request.AddField(milvus::FieldSchema("id", milvus::DataType::INT64, "", true, true));
request.AddField(milvus::FieldSchema("text", milvus::DataType::VARCHAR, "", false, false, 2000));
request.AddField(milvus::FieldSchema("sparse_vector", milvus::DataType::SPARSE_FLOAT_VECTOR, "", false, false));
request.AddFunction(milvus::FunctionSchema("text_bm25", milvus::FunctionType::BM25, {"text"}, {"sparse_vector"}));
status = client->CreateCollection(request);
if (!status.IsOk()) {
std::cerr << status.Message() << std::endl;
}
// index + insert + SEARCH_PARAMS (see full text search guide)
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
const COLLECTION_NAME = "highlighter_demo";
if (await client.hasCollection({ collection_name: COLLECTION_NAME })) {
await client.dropCollection({ collection_name: COLLECTION_NAME });
}
await client.createCollection({
collection_name: COLLECTION_NAME,
schema: [
{ name: "id", data_type: DataType.Int64, is_primary_key: true, auto_id: true },
{ name: "text", data_type: DataType.VarChar, max_length: 2000, enable_analyzer: true, enable_match: true },
{ name: "sparse_vector", data_type: DataType.SparseFloatVector },
],
functions: [
{
name: "text_bm25",
type: "BM25",
input_field_names: ["text"],
output_field_names: ["sparse_vector"],
},
],
index_params: [
{
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 },
},
],
});
const 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.",
];
await client.insert({ collection_name: COLLECTION_NAME, data: docs.map(text => ({ text })) });
const SEARCH_PARAMS = { params: { drop_ratio_search: 0.0 } };
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
var client = new MilvusClientV2(new ConnectConfig { Uri = "YOUR_CLUSTER_ENDPOINT" });
const string collectionName = "highlighter_demo";
// Clean up existing collection
if ((await client.HasCollectionAsync(new HasCollectionReq { CollectionName = collectionName })).Has)
{
await client.DropCollectionAsync(new DropCollectionReq { CollectionName = collectionName });
}
// Define schema
var schema = new CollectionSchema { Name = collectionName };
schema.Fields.Add(new FieldSchema("id", DataType.Int64, isPrimaryKey: true, autoId: true));
schema.Fields.Add(FieldSchema.CreateVarchar("text", maxLength: 2000, enableAnalyzer: true, enableMatch: true));
schema.Fields.Add(new FieldSchema("sparse_vector", DataType.SparseFloatVector));
schema.Functions.Add(FunctionSchema.CreateBm25("text_bm25", "text", "sparse_vector"));
// Create collection and index
await client.CreateCollectionAsync(new CreateCollectionReq
{
CollectionName = collectionName,
Schema = schema,
Indexes = new[] { new IndexParam("sparse_vector", null, IndexType.SparseInvertedIndex, MetricType.Bm25)
{
ExtraParams = { ["inverted_index_algo"] = "DAAT_MAXSCORE", ["bm25_k1"] = "1.2", ["bm25_b"] = "0.75" }
} }
});
// Insert sample documents
string[] 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."
];
await client.InsertAsync(new InsertReq
{
CollectionName = collectionName,
RowsData = docs.Select(text => (IDictionary<string, object?>)new Dictionary<string, object?> { ["text"] = text }).ToList()
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
例 1: BM25 全文検索で検索語句をハイライト
この例では、BM25 全文検索で検索語句をハイライトする方法を示します。
-
BM25 全文検索では、
"test"を検索語句として使用します。 -
Highlighter は、"test" のすべての出現箇所を
{タグと}タグで囲みます。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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', {}).get('fragments', [])}")
print()
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
String COLLECTION_NAME = "highlighter_demo";
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new EmbeddedText("test")))
.annsField("sparse_vector")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true);
let res = client
.search(
SearchRequest::builder()
.collection_name(COLLECTION_NAME)
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["test".to_string()]))
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
const std::string COLLECTION_NAME = "highlighter_demo";
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
auto request = milvus::SearchRequest()
.WithCollectionName(COLLECTION_NAME)
.WithAnnsField("sparse_vector")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("test")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const COLLECTION_NAME = "highlighter_demo";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
};
const res = await client.search({
collection_name: COLLECTION_NAME,
data: ["test"],
anns_field: "sparse_vector",
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
const string collectionName = "highlighter_demo";
var highlighter = new SearchParameters
{
OutputFields = { "text" },
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]",
["post_tags"] = "[\"}\"]",
["highlight_search_text"] = "true" // Highlight BM25 query terms
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = collectionName,
VectorFieldName = "sparse_vector",
Texts = new[] { "test" },
MetricType = MetricType.Bm25,
Limit = 10,
Parameters = highlighter
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
期待される出力
['{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"をハイライトリストに追加します。 -
Highlighter は、一致したすべての語句(
"my"、"test"、"doc")を{と}で囲みます。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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', {}).get('fragments', [])}")
print()
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
String COLLECTION_NAME = "highlighter_demo";
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.addHighlightQuery(new LexicalHighlighter.HighlightQuery("TextMatch", "text", "my doc"))
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new EmbeddedText("test")))
.annsField("sparse_vector")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true)
.add_highlight_query(HighlightQuery::new()
.query_type("TextMatch")
.field("text")
.text("my doc"));
let res = client
.search(
SearchRequest::builder()
.collection_name(COLLECTION_NAME)
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["test".to_string()]))
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
const std::string COLLECTION_NAME = "highlighter_demo";
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
highlighter->AddHighlightQuery("TextMatch", "text", "my doc");
auto request = milvus::SearchRequest()
.WithCollectionName(COLLECTION_NAME)
.WithAnnsField("sparse_vector")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("test")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const COLLECTION_NAME = "highlighter_demo";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
highlight_query: [
{ type: "TextMatch", field: "text", text: "my doc" },
],
};
const res = await client.search({
collection_name: COLLECTION_NAME,
data: ["test"],
anns_field: "sparse_vector",
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
const string collectionName = "highlighter_demo";
var highlighter = new SearchParameters
{
OutputFields = { "text" },
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]",
["post_tags"] = "[\"}\"]",
["highlight_search_text"] = "true", // Also highlight BM25 term
["highlight_query"] = "[{\"type\":\"TextMatch\",\"field\":\"text\",\"text\":\"my doc\"}]"
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = collectionName,
VectorFieldName = "sparse_vector",
Texts = new[] { "test" },
MetricType = MetricType.Bm25,
Limit = 10,
Parameters = highlighter
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
期待される出力
['{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)。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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', {}).get('fragments', [])
print(f" Doc {i+1}: {frags}")
print()
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
String COLLECTION_NAME = "highlighter_demo";
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.fragmentOffset(20)
.fragmentSize(60)
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new EmbeddedText("Milvus")))
.annsField("sparse_vector")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true)
.fragment_offset(20)
.fragment_size(60);
let res = client
.search(
SearchRequest::builder()
.collection_name(COLLECTION_NAME)
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["Milvus".to_string()]))
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
const std::string COLLECTION_NAME = "highlighter_demo";
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
highlighter->WithFragmentOffset(20);
highlighter->WithFragmentSize(60);
auto request = milvus::SearchRequest()
.WithCollectionName(COLLECTION_NAME)
.WithAnnsField("sparse_vector")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("Milvus")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const COLLECTION_NAME = "highlighter_demo";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
fragment_offset: 20,
fragment_size: 60,
};
const res = await client.search({
collection_name: COLLECTION_NAME,
data: ["Milvus"],
anns_field: "sparse_vector",
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
const string collectionName = "highlighter_demo";
var highlighter = new SearchParameters
{
OutputFields = { "text" },
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]",
["post_tags"] = "[\"}\"]",
["highlight_search_text"] = "true",
["fragment_offset"] = "20", // Keep 20 chars before match
["fragment_size"] = "60" // Max ~60 chars per fragment
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = collectionName,
VectorFieldName = "sparse_vector",
Texts = new[] { "Milvus" },
MetricType = MetricType.Bm25,
Limit = 10,
Parameters = highlighter
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
期待される出力
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 全文検索で複数のクエリを使用して検索する場合、各クエリの結果は独立してハイライトされます。1 つ目のクエリの結果にはその検索語句のハイライトが含まれ、2 つ目のクエリの結果にはその検索語句のハイライトが含まれます。以下同様です。各クエリは同じ highlighter 設定を使用しますが、それぞれ独立して適用します。
次の例では:
-
1 つ目のクエリは、結果セット内の
"test"をハイライトします。 -
2 つ目のクエリは、結果セット内の
"Milvus"をハイライトします。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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', {}).get('fragments', [])}")
print()
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
String COLLECTION_NAME = "highlighter_demo";
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("{"))
.postTags(Arrays.asList("}"))
.highlightSearchText(true)
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Arrays.asList(new EmbeddedText("test"), new EmbeddedText("Milvus")))
.annsField("sparse_vector")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["{"])
.post_tags(["}"])
.highlight_search_text(true);
let res = client
.search(
SearchRequest::builder()
.collection_name(COLLECTION_NAME)
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["test".to_string(), "Milvus".to_string()]))
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
const std::string COLLECTION_NAME = "highlighter_demo";
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"{"});
highlighter->WithPostTags({"}"});
highlighter->WithHighlightSearchText(true);
auto request = milvus::SearchRequest()
.WithCollectionName(COLLECTION_NAME)
.WithAnnsField("sparse_vector")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("test")
.AddEmbeddedText("Milvus")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const COLLECTION_NAME = "highlighter_demo";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["{"],
post_tags: ["}"],
highlight_search_text: true,
};
const res = await client.search({
collection_name: COLLECTION_NAME,
data: ["test", "Milvus"],
anns_field: "sparse_vector",
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
const string collectionName = "highlighter_demo";
var highlighter = new SearchParameters
{
OutputFields = { "text" },
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"{\"]",
["post_tags"] = "[\"}\"]",
["highlight_search_text"] = "true"
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = collectionName,
VectorFieldName = "sparse_vector",
Texts = new[] { "test", "Milvus" }, // Two queries
MetricType = MetricType.Bm25,
Limit = 2,
Parameters = highlighter
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
期待される出力
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 タグ
ハイライトには、Web UI 向けの HTML セーフなタグなど、任意のタグを使用できます。これは、ブラウザーで検索結果をレンダリングする場合に便利です。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- CSharp
- cURL
- Zilliz CLI
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', {}).get('fragments', [])}")
print()
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.highlighter.LexicalHighlighter;
import io.milvus.v2.common.IndexParam;
import java.util.*;
String COLLECTION_NAME = "highlighter_demo";
LexicalHighlighter highlighter = LexicalHighlighter.builder()
.preTags(Arrays.asList("<mark>"))
.postTags(Arrays.asList("</mark>"))
.highlightSearchText(true)
.build();
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new EmbeddedText("test")))
.annsField("sparse_vector")
.topK(10)
.outputFields(Collections.singletonList("text"))
.metricType(IndexParam.MetricType.BM25)
.highlighter(highlighter)
.build();
SearchResp searchResp = client.search(searchReq);
// Note: the highlighter is not yet supported in milvus-sdk-go.
use milvus::v2::prelude::*;
let highlighter = LexicalHighlighter::new()
.pre_tags(["<mark>"])
.post_tags(["</mark>"])
.highlight_search_text(true);
let res = client
.search(
SearchRequest::builder()
.collection_name(COLLECTION_NAME)
.vector_field("sparse_vector")
.vectors(SearchVectors::EmbeddedText(vec!["test".to_string()]))
.limit(10)
.metric_type(MetricType::Bm25)
.output_fields(["text"])
.highlighter(highlighter)
.build()?,
)
.await?;
const std::string COLLECTION_NAME = "highlighter_demo";
auto highlighter = std::make_shared<milvus::LexicalHighlighter>();
highlighter->WithPreTags({"<mark>"});
highlighter->WithPostTags({"</mark>"});
highlighter->WithHighlightSearchText(true);
auto request = milvus::SearchRequest()
.WithCollectionName(COLLECTION_NAME)
.WithAnnsField("sparse_vector")
.WithLimit(10)
.AddOutputField("text")
.AddEmbeddedText("test")
.WithHighlighter(highlighter);
milvus::SearchResponse response;
auto status = client->Search(request, response);
import { HighlightType } from "@zilliz/milvus2-sdk-node";
const COLLECTION_NAME = "highlighter_demo";
const highlighter = {
type: HighlightType.Lexical,
pre_tags: ["<mark>"],
post_tags: ["</mark>"],
highlight_search_text: true,
};
const res = await client.search({
collection_name: COLLECTION_NAME,
data: ["test"],
anns_field: "sparse_vector",
limit: 10,
output_fields: ["text"],
highlighter,
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Collection;
using Milvus.Client.V2.Requests.Dml;
using Milvus.Client.V2.Requests.Dql;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;
const string collectionName = "highlighter_demo";
var highlighter = new SearchParameters
{
OutputFields = { "text" },
HighlightType = HighlightType.Lexical,
Highlighter =
{
["pre_tags"] = "[\"<mark>\"]",
["post_tags"] = "[\"</mark>\"]",
["highlight_search_text"] = "true"
}
};
var results = await client.SearchAsync(new SearchReq
{
CollectionName = collectionName,
VectorFieldName = "sparse_vector",
Texts = new[] { "test" },
MetricType = MetricType.Bm25,
Limit = 2,
Parameters = highlighter
});
# Note: the highlighter is not yet supported in the RESTful API.
# Zilliz CLI
期待される出力
['<mark>test</mark> doc']
['<mark>test</mark> doc']