文本字段Compatible with Milvus 3.0.x

在 AI 搜索应用中,向量搜索可帮助您查找语义相似的实体,但应用通常还需要每个匹配结果背后的原始源文本。大型语言模型(LLM)或 Agents 可以利用该文本作为上下文,用于阅读、引用、摘要,或将结果纳入提示词中。

Milvus 提供了TEXT 标量字段类型,用于将长源文本直接与实体关联存储。典型值包括段落、长文档、文章正文、工单和日志。与VARCHAR 不同,后者要求设置固定的max_length ,而TEXT 则无需在 Collection Schema 中设置最大字节长度。

要定义TEXT 字段,请将datatype 设置为DataType.TEXT

此功能需要 Storage V3。有关启用说明和兼容性注意事项,请参阅Storage V3

common.storage.useLoonFFI 默认值为 `false`,这意味着 Storage V3 默认处于禁用状态。在创建包含 `TEXT ` 字段的 Collection 之前,请将此参数设置为 `true`;否则,Milvus 将拒绝该 Collection Schema。

schema.add_field(
    field_name="content",
    datatype=DataType.TEXT,
)

定义字段后,每个实体都可以在该字段中包含一个字符串值。您可以像处理其他标量字段一样插入TEXT 值,并通过在output_fields 中列出该字段,从查询或搜索结果中返回这些值。

TEXT 字段支持空值。要启用此功能,请将nullable 设置为True 。有关详细信息,请参阅“可为空字段”

限制

  • TEXT 字段不能作为主字段、Partition Key或聚簇键。
  • TEXT 不能用作ARRAY 字段的元素类型,包括StructArray 中的标量子字段。
  • 在 Milvus 3.0.0 中,TEXT 字段不支持默认值。
  • 在 Milvus 3.0.0 中,外部 Collection 不支持 `TEXT ` 字段。
  • 用户无法在TEXT 字段上创建标量索引。当enable_match=True 时,Milvus 会构建一个由系统管理的文本索引,用于文本匹配。此内部索引并非用户创建的标量索引。
  • 一般的标量过滤操作符无法直接应用于 `TEXT ` 字段。 这些包括比较操作符(如==!= )、范围操作符(如>>=<<= ),以及INLIKE 、正则表达式操作符(=~!~ )和IS NULLIS NOT NULL 。若要按分析后的术语进行过滤,请使用enable_analyzer=Trueenable_match=True 定义字段,并使用TEXT_MATCHTEXT_MATCH_FUZZY 。对于按相关性排序的全文检索,请使用 BM25。
  • 在 Milvus 3.0.0 中,若要使用以TEXT 字段作为输入的 BM25 或 MinHash 函数,必须在创建 Collection 时进行定义。即使现有 Collection 为空,也无法通过add_function_fieldAlterCollectionSchema 在后续添加该函数,因为 Milvus 无法根据存储的TEXT 值回填该函数的输出结果。 若要将此类函数添加到现有Collection中,请使用VARCHAR 输入字段,或在重新创建Collection时将其包含在Schema中。有关添加函数及其生成的向量字段的详细信息,请参阅“修改Collection Schema”
  • 文本嵌入函数也必须在创建 Collection 时定义。Milvus 3.0.0 不支持在运行时添加这些函数。

选择 TEXT 或 VARCHAR

TEXTVARCHAR 均用于存储字符串值,但它们支持不同的应用需求。请使用VARCHAR 来存储用于识别、分类或过滤实体的简短、有限元数据。请使用TEXT 来存储较长的源内容,以便为大型语言模型(LLM)或Agents提供足够的上下文,用于阅读、引用、摘要或构建提示词。

方面VARCHARTEXT
最适合用于识别、分类或筛选实体的短元数据,例如titletagcategoryexternal_id用于 LLM 或 Agents 工作流的较长源内容,例如contentpassagearticle_bodylog_message
长度设置需要max_length ,该字段定义了该字段可存储的最大字节数。最大值为65,535 字节。如果值可能超过此限制,请使用TEXT不要求max_length ,因此Schema无需为文本值设定固定的字节限制。
存储行为将每个值存储在字段配置的max_length 内。对于较大的文本值,将使用自动存储选择机制。有关详细信息,请参阅《Milvus 如何存储大型 TEXT 值》。
主字段支持可作为主字段使用。不能用作主字段。
过滤适用于需要出现在过滤表达式中的短字符串元数据,例如category == "news"tag in ["ai", "database"]不支持一般的标量过滤操作符。请使用支持匹配的文本操作符进行分析术语过滤,或使用 BM25 进行相关性排序的全文检索。

有关VARCHAR 字段的详细信息,请参阅“VarChar 字段”。

Milvus 如何存储大型 TEXT 值

展开以查看工作原理

当您插入一个实体时,您为TEXT 字段提供的字符串即为TEXT 值。Milvus 会将该值的大小与dataNode.text.inlineThreshold 进行比较(默认值为65,536 字节),然后选择两种内部存储路径中的一种。

Large text storage 大文本存储

  • 内联存储:如果TEXT 值小于dataNode.text.inlineThreshold ,Milvus 会将原始文本值直接存储在TEXT 字段 data 中。
  • LOB 存储:如果 `TEXT ` 的值大于或等于 `dataNode.text.inlineThreshold`,Milvus 会将该值视为大对象,并将原始文本单独存储在对象存储(如 MinIO)中。`TEXT ` 字段数据中存储的是指向该单独存储文本的内部引用。当在查询或搜索结果中请求 `TEXT ` 字段时,Milvus 会使用该引用检索并返回原始文本。

此存储选择属于内部机制。无论 Milvus 使用何种存储路径,您对TEXT 字段的插入、查询和搜索操作方式均保持一致。若需调整阈值或相关存储、压缩及垃圾回收行为,请参阅与dataNode 相关的配置和 与 dataCoord 相关的配置

如果您的部署使用对象存储,较大的 `TEXT ` 值可能会以 Milvus 管理的对象形式出现在诸如lobs/... 之类的路径下。这些对象属于实现细节,不应手动移动、复制或删除。 在删除实体、删除分区或压缩数据后,只有当 Milvus 垃圾回收在安全窗口期结束后移除了未被引用的巨型对象数据,对象存储的使用量才会减少。

TEXT 的常见用途是配合 BM25 进行全文搜索。在此模式下,TEXT 字段存储原始源内容,BM25 分析文本并生成稀疏向量,用于对基于关键词的匹配结果进行排序。搜索结果随后可返回匹配的TEXT 值,作为 LLM 或 Agents 工作流的上下文。 以下示例演示了如何将TEXT 字段用作BM25的输入字段。如需了解全文搜索的概念和查询选项,请参阅《全文搜索》。

步骤 1:创建包含 TEXT 字段的 Collection

以下示例创建了一个Collection,其中包含用于源内容的TEXT 字段,以及用于存储BM25生成的稀疏向量向量字段。BM25函数将content 中的分词文本转换为稀疏向量向量,并将其存储在sparse 中。

对于 BM25 全文搜索,输入的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)

步骤 2:创建稀疏向量索引

在由 BM25 函数生成的稀疏向量字段上创建索引。度量类型必须设置为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,
)

步骤 3:插入 TEXT 数据

将文本直接插入TEXT 字段。请勿为sparse 字段提供值。Milvus会通过将BM25函数应用于content ,在内部生成稀疏向量。

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)

使用原始查询文本作为搜索数据,并对稀疏向量字段进行搜索。Milvus会将查询文本转换为稀疏向量,使用BM25算法对匹配结果进行排序,并将请求的TEXT 字段结果返回至output_fields 字段中。

results = client.search(
    collection_name=COLLECTION_NAME,
    data=["how does Milvus store source text for retrieval"],
    anns_field="sparse",
    limit=2,
    output_fields=["content"],
)

步骤 5:读取返回的 TEXT 值

每个搜索命中结果都包含 BM25 得分和原始的TEXT 值。

for hit in results[0]:
    print(f"id: {hit['id']}, score: {hit['distance']}")
    print(hit["entity"]["content"])

有关 BM25 函数、稀疏向量索引以及全文搜索查询语法的更多信息,请参阅《全文搜索》。

翻译自DeepL

想要更快、更简单、更好用的 Milvus SaaS服务 ?

Zilliz Cloud是基于Milvus的全托管向量数据库,拥有更高性能,更易扩展,以及卓越性价比

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?