Lexical Highlighter
Zilliz Cloud 中的 Highlighter 会在文本字段中对匹配到的词项进行标注,通过在其前后包裹可自定义的标签来实现高亮显示。高亮有助于解释文档为何被命中,提升结果的可读性,并支持在搜索与 RAG 应用中的富文本渲染。
高亮是在最终搜索结果集上的后处理步骤执行的。它不会影响候选召回、过滤逻辑、排序或打分。
Highlighter 提供了三个彼此独立的控制维度:
-
高亮哪些词项
你可以选择高亮词项的来源。例如,高亮 BM25 Full Text Search 中使用的搜索词,或在基于文本的过滤表达式(如 TEXT_MATCH 条件)中指定的查询词。
-
如何渲染高亮词项
你可以通过配置每个匹配项前后插入的标签来控制高亮的呈现方式。例如,使用
{}这样的简单标记,或使用<em></em>等 HTML 标签进行富文本渲染。 -
如何返回高亮文本
你可以控制高亮结果以片段(fragment)的形式返回,包括片段的起始位置、长度以及返回的片段数量。
以下各节将分别介绍这些使用场景。
BM25 Full Text Search 中的搜索词高亮
在执行 BM25 Full Text Search 时,你可以对返回结果中的搜索词进行高亮显示,以帮助解释文档为何与查询匹配。有关 BM25 全文搜索的更多信息,请参阅 Full Text Search。
在该场景中,被高亮的词项直接来源于 BM25 Full Text Search 中使用的搜索词。Highlighter 会使用这些词项,对最终结果中的匹配文本进行标注。
假设某个文本字段中存储了如下内容:
Milvus supports full text search. Use BM25 for keyword relevance. Filters can narrow results.
Highlighter 配置
要在 BM25 Full Text Search 中高亮搜索词,需要创建一个 LexicalHighlighter,并为 BM25 Full Text Search 启用搜索词高亮:
- 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表示让 Zilliz Cloud 使用 BM25 Full Text Search 中的搜索词作为高亮词项的来源。
创建 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 字段返回高亮文本。默认情况下,高亮结果以片段(fragment)的形式返回,片段从第一个匹配到的词项开始。
在该示例中,搜索词为 "BM25",因此它会在返回结果中被高亮显示:
{
...,
"highlight": {
"text": [
"{BM25} for keyword relevance. Filters can narrow results."
]
}
}
如需控制返回片段的位置、长度以及返回的片段数量,请参阅基于片段的高亮输出。
过滤条件中的查询词高亮
除了高亮搜索词之外,你还可以对基于文本的过滤表达式中使用的查询词进行高亮显示。
- 当前仅支持对 TEXT_MATCH 过滤条件中的查询词进行高亮。更多信息请参阅 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 字段返回高亮文本。默认情况下,高亮结果以片段(fragment)的形式返回,并从第一个匹配到的词项开始。
在该示例中,第一个匹配到的词项是 "text",因此返回的高亮文本会从该位置开始:
{
...,
"highlight": {
"text": [
"{text} {filtering} works in Milvus."
]
}
}
如需控制返回片段的位置、长度以及返回的片段数量,请参阅基于片段的高亮输出。
基于片段的高亮输出
默认情况下,Zilliz Cloud 会将高亮文本以片段(fragment)的形式返回,并从第一个匹配到的词项开始。通过与片段相关的配置参数,你可以进一步控制片段的返回方式,而无需改变哪些词项会被高亮。
假设某个文本字段中存储了如下内容:
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 对象后,将其配置应用到搜索请求中:
- 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,因此只返回一个片段。 -
片段的长度受到
fragment_size的限制。
示例
准备工作
在使用 Highlighter 之前,请确保你的集合已正确配置。
下面的示例将创建一个同时支持 BM25 Full Text Search 和 TEXT_MATCH 查询 的 Collection,并向其中插入示例文档。
准备 Collection
- 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 Full Text Search 中高亮搜索词
本示例演示了如何在 BM25 Full Text Search 中对搜索词进行高亮显示。
-
BM25 Full Text Search 使用
"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 Full Text Search 使用
"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 Full Text Search 中使用多个查询时,每个查询的结果都会独立进行高亮。第一个查询返回的结果只包含其搜索词的高亮,第二个查询返回的结果只包含其搜索词的高亮,依此类推。所有查询共享同一套 Highlighter 配置,但会分别独立应用。
在下面的示例中:
-
第一个查询在其结果集中高亮
"test" -
第二个查询在其结果集中高亮
"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']