Text Field
在 AI search 应用中,vector search 可以帮助你找到语义相似的 Entity,但应用通常还需要每个匹配结果背后的原始源文本。LLM 或 agent 可以将该文本用作上下文,用于阅读、引用、总结,或将结果包含在 prompt 中。
Milvus 提供 TEXT 标量字段类型,用于直接随 Entity 存储较长的源文本。典型值包括段落、长文档、文章正文、工单和日志。与需要固定 max_length 的 VARCHAR 不同,TEXT 不要求你在 Collection Schema 中设置最大字节长度。
要定义 TEXT 字段,请将 datatype 设置为 DataType.TEXT。
此功能需要 Storage V3。有关启用说明和兼容性注意事项,请参阅 Storage V3。
如果 Storage V3 处于禁用状态,Milvus 会拒绝包含 TEXT 字段的 Collection Schema。
schema.add_field(
field_name="content",
datatype=DataType.TEXT,
)
定义字段后,每个 Entity 都可以在该字段中包含一个字符串值。你可以像插入其他标量字段一样插入 TEXT 值,并通过在 output_fields 中列出该字段,从 query 或 search 结果中返回这些值。
TEXT 字段支持 NULL 值。要启用此功能,请将 nullable 设置为 True。详情请参阅 Nullable Field。
Limits
TEXT字段不能作为 primary field。Primary field 支持INT64和VARCHAR。- 在 Milvus 3.0.0 中,
TEXT字段不支持PHRASE_MATCH。 - 在 Milvus 3.0.0 中,
TEXT字段不支持默认值。 - 在 Milvus 3.0.0 中,外部 Collection 不支持
TEXT字段。 - 在 Milvus 3.0.0 中,
TEXT字段不支持 scalar index。 TEXT不适用于常规元数据过滤。如果你需要基于短字符串元数据进行过滤,且字段值满足VARCHAR长度限制,请使用VARCHAR。
选择 TEXT 或 VARCHAR
TEXT 和 VARCHAR 都用于存储字符串值,但适用于不同的应用需求。对于用于标识、分类或过滤 Entity 的短小、有界元数据,请使用 VARCHAR。对于较长的源内容,如果需要为 LLM 或 agent 提供足够上下文来阅读、引用、总结或构建 prompt,请使用 TEXT。
| 方面 | VARCHAR | TEXT |
|---|---|---|
| 最适合 | 用于标识、分类或过滤 Entity 的短元数据,例如 title、tag、category 或 external_id。 | 用于 LLM 或 agent 工作流的较长源内容,例如 content、passage、article_body 或 log_message。 |
| 长度设置 | 需要 max_length,用于定义该字段可存储的最大字节数。最大值为 65,535 字节。如果某个值可能超过此限制,请使用 TEXT。 | 不需要 max_length,因此 Schema 无需为文本值设置固定字节限制。 |
| 存储行为 | 在字段配置的 max_length 范围内存储每个值。 | 对较大的文本值使用自动存储选择。详情请参阅 Milvus 如何存储大型 TEXT 值。 |
| Primary field 支持 | 可用作 Primary field。 | 不能用作 Primary field。 |
| 过滤 | 用于需要出现在 Filter 表达式中的短字符串元数据,例如 category == "news" 或 tag in ["ai", "database"]。 | 不适合用于常规元数据过滤。 |
有关 VARCHAR 字段的详细信息,请参阅 VarChar Field。
How Milvus stores large TEXT values
展开查看工作原理
插入 Entity 时,你为 TEXT 字段提供的字符串就是 TEXT 值。Milvus 会将该值的大小与 dataNode.text.inlineThreshold 进行比较。该阈值默认为 65,536 字节,然后 Milvus 会选择以下两种内部存储路径之一。

- Inline storage:如果
TEXT值小于dataNode.text.inlineThreshold,Milvus 会将原始文本值直接存储在TEXT字段数据中。 - LOB storage:如果
TEXT值大于或等于dataNode.text.inlineThreshold,Milvus 会将该值视为大对象,并将原始文本单独存储在对象存储中,例如 MinIO。TEXT字段数据会存储一个指向该独立文本的内部引用。当查询或搜索结果请求TEXT字段时,Milvus 会使用该引用检索并返回原始文本。
这种存储选择是内部行为。无论 Milvus 使用哪种存储路径,你插入、查询和搜索 TEXT 字段的方式都相同。如需调整阈值,或调整相关的存储、Compaction 和垃圾回收行为,请参阅 dataNode-related Configurations 和 dataCoord-related Configurations。
如果你的部署使用对象存储,大型 TEXT 值可能会以 Milvus 管理对象的形式出现在 lobs/... 等路径下。这些对象属于实现细节,不应手动移动、复制或删除。删除 Entity、删除 Partition 或执行 Compaction 后,只有在 Milvus 垃圾回收经过安全窗口并移除未引用的大对象数据之后,对象存储用量才可能下降。
TEXT 的一个常见用途是结合 BM25 进行 Full Text Search。在这种模式下,TEXT 字段存储原始源内容,BM25 会分析文本并生成 sparse vectors,用于对基于关键词的匹配结果进行排序。随后,搜索结果可以返回匹配的 TEXT 值,作为 LLM 或 Agent 工作流的上下文。以下示例展示如何将 TEXT 字段用作 BM25 的输入字段。如需了解 Full Text Search 的概念和查询选项,请参阅 Full Text Search。
Step 1:创建包含 TEXT 字段的 Collection
以下示例创建一个 Collection,其中包含用于源内容的 TEXT 字段,以及用于存储 BM25 生成的稀疏向量的 sparse vector 字段。BM25 function 会将 content 中经过 Analyzer 分词的文本转换为稀疏向量,并存储在 sparse 中。
对于 BM25 Full Text Search,输入 TEXT 字段必须设置 enable_analyzer=True。
from pymilvus import DataType, Function, FunctionType, MilvusClient
client = MilvusClient(uri="http://localhost:19530")
COLLECTION_NAME = "text_bm25_collection"
if client.has_collection(COLLECTION_NAME):
client.drop_collection(COLLECTION_NAME)
schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(
field_name="content",
datatype=DataType.TEXT,
enable_analyzer=True,
)
schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR)
bm25_function = Function(
name="content_bm25",
input_field_names=["content"],
output_field_names=["sparse"],
function_type=FunctionType.BM25,
)
schema.add_function(bm25_function)
Step 2: Create a sparse vector index
为 BM25 function 生成的 sparse vector 字段创建 Index。metric type 必须设置为 BM25。
index_params = client.prepare_index_params()
index_params.add_index(
field_name="sparse",
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,
)
Step 3: Insert TEXT data
将文本直接插入 TEXT 字段。不要为 sparse 字段提供值。Milvus 会在内部对 content 应用 BM25 function 来生成 sparse vectors。
data = [
{
"id": 1,
"content": "Milvus stores vector embeddings and scalar fields in collections. It supports vector search, full text search, and metadata filtering for retrieval applications.",
},
{
"id": 2,
"content": "Long documents are often split into passages before embedding. Store each passage in a TEXT field so search results can return the source text.",
},
{
"id": 3,
"content": "Operational logs and support tickets often contain long natural-language text. TEXT fields can store these values without a fixed max_length setting.",
},
]
client.insert(collection_name=COLLECTION_NAME, data=data)
client.load_collection(collection_name=COLLECTION_NAME)
Step 4: Perform BM25 full text search
使用原始查询文本作为搜索数据,并针对 sparse vector 字段进行搜索。Milvus 会将查询文本转换为 sparse vector,使用 BM25 对匹配结果进行排序,并在 output_fields 中返回请求的 TEXT 字段。
results = client.search(
collection_name=COLLECTION_NAME,
data=["how does Milvus store source text for retrieval"],
anns_field="sparse",
limit=2,
output_fields=["content"],
)
Step 5: 读取返回的 TEXT 值
每个 search hit 都包含 BM25 分数和原始 TEXT 值。
for hit in results[0]:
print(f"id: {hit['id']}, score: {hit['distance']}")
print(hit["entity"]["content"])
有关 BM25 functions、sparse vector indexes 以及 Full Text Search 查询语法的更多信息,请参阅 Full Text Search。