テキストフィールドCompatible with Milvus 3.0.x

AI検索アプリケーションにおいて、ベクトル検索は意味的に類似したエンティティを見つけるのに役立ちますが、多くの場合、各一致結果の背後にある元のソーステキストもアプリケーションに必要となります。LLMやエージェントは、そのテキストをコンテキストとして利用し、読み上げ、引用、要約、あるいはプロンプトに結果を含めることができます。

Milvusでは、長いソーステキストをエンティティと共に直接格納するためのスカラーフィールド型「TEXT 」を提供しています。代表的な値としては、文章の抜粋、長文のドキュメント、記事本文、チケット、ログなどが挙げられます。固定のmax_length を必要とするVARCHAR とは異なり、TEXT では、コレクションスキーマで最大バイト長を設定する必要はありません。

TEXT フィールドを定義するには、datatypeDataType.TEXT に設定します。

この機能を利用するには、Storage V3 が必要です。有効化の手順および互換性に関する注意事項については、「Storage V3」を参照してください。

common.storage.useLoonFFI デフォルト値は `false` であり、これは Storage V3 がデフォルトで無効になっていることを意味します。TEXT フィールドを含むコレクションを作成する前に、このパラメータを `true` に設定してください。そうしないと、Milvus はそのコレクションスキーマを拒否します。

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

フィールドの定義後、各エンティティはそのフィールドに文字列値を格納できるようになります。TEXT の値は他のスカラーフィールドと同様に挿入でき、クエリや検索結果から取得するには、output_fields でそのフィールドを指定します。

TEXT フィールドはNULL値をサポートしています。この機能を有効にするには、nullableTrue に設定します。詳細については、「Nullable Field」を参照してください。

制限事項

  • TEXT フィールドは、プライマリフィールド、パーティションキー、またはクラスタリングキーにはできません。
  • TEXT は、ARRAY フィールドの要素型として使用できません。これには、StructArray 内のスカラーサブフィールドも含まれます。
  • Milvus 3.0.0 では、TEXT フィールドはデフォルト値をサポートしていません。
  • Milvus 3.0.0 では、外部コレクションでの `TEXT ` フィールドはサポートされていません。
  • ユーザーは、TEXT フィールドに対してスカラーインデックスを作成することはできません。enable_match=True の場合、Milvusはテキストマッチング用にシステム管理のテキストインデックスを構築します。この内部インデックスは、ユーザーが作成したスカラーインデックスではありません。
  • 一般的なスカラーフィルタ演算子は、TEXT フィールドに直接適用することはできません。 これには、==!= などの比較演算子、>>=<<= などの範囲演算子、INLIKE 、正規表現演算子(=~ および!~ )、ならびにIS NULLIS NOT NULL などが含まれます。分析済み用語でフィルタリングするには、フィールドをenable_analyzer=True およびenable_match=True で定義し、TEXT_MATCH またはTEXT_MATCH_FUZZY を使用します。関連度順の全文検索には、BM25を使用してください。
  • Milvus 3.0.0 では、TEXT フィールドを入力として使用する BM25 または MinHash 関数は、コレクションの作成時に定義する必要があります。既存のコレクションが空であっても、add_function_fieldAlterCollectionSchema を通じて後から追加することはできません。これは、Milvus が保存されたTEXT の値から関数の出力を遡及的に生成できないためです。 既存のコレクションにこのような関数を追加するには、VARCHAR 入力フィールドを使用するか、そのスキーマに関数を含めてコレクションを再作成してください。関数およびそれによって生成されるベクトルフィールドの追加に関する詳細については、「Alter Collection Schema」を参照してください。
  • テキスト埋め込み関数も、コレクションの作成時に定義する必要があります。Milvus 3.0.0 では、実行時にこれらを追加することはサポートされていません。

TEXT または VARCHAR

TEXTVARCHAR はどちらも文字列値を格納しますが、サポートするアプリケーションのニーズが異なります。エンティティの識別、分類、またはフィルタリングを行う、短く範囲が限定されたメタデータには、VARCHAR を使用します。LLMやエージェントが読み取り、引用、要約、またはプロンプトを作成するのに十分なコンテキストを提供する、より長いソースコンテンツには、TEXT を使用します。

側面VARCHARTEXT
最適な用途エンティティの識別、分類、フィルタリングに使用される短いメタデータ(例:titletagcategoryexternal_id など)。contentpassagearticle_bodylog_message など、LLM やエージェントのワークフローで使用される、より長いソースコンテンツ。
長さの設定max_length が必要です。これは、フィールドが格納できる最大バイト数を定義します。最大値は65,535 バイトです。値がこの制限を超える可能性がある場合は、TEXT を使用してください。max_length は不要であるため、スキーマにテキスト値の固定バイト制限を設定する必要はありません。
格納の動作各値は、フィールドに設定されたmax_length 内に格納されます。大きなテキスト値については、自動ストレージ選択が使用されます。詳細については、「Milvus による大きな TEXT 値の保存方法」を参照してください。
プライマリフィールドとしてのサポートプライマリフィールドとして使用可能です。プライマリフィールドとしては使用できません。
フィルタリングcategory == "news"tag in ["ai", "database"] など、フィルタ式に含める必要がある短い文字列のメタデータに使用します。一般的なスカラーフィルタ演算子はサポートされていません。分析済み用語のフィルタリングには、マッチ対応のテキスト演算子を使用するか、関連度順にランク付けされた全文検索には BM25 を使用してください。

VARCHAR フィールドの詳細については、「VarChar フィールド」を参照してください。

Milvus による大規模な TEXT 値の保存方法

展開して仕組みを確認

エンティティを挿入する際、TEXT フィールドに指定する文字列が、TEXT 値となります。Milvus は、その値のサイズをdataNode.text.inlineThreshold(デフォルトでは65,536 バイト)と比較し、2 つの内部保存パスのいずれかを選択します。

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 値は、lobs/... などのパス下にMilvusが管理するオブジェクトとして表示されることがあります。これらのオブジェクトは実装上の詳細であり、手動で移動、コピー、または削除してはなりません。 エンティティの削除、パーティションの削除、またはデータの圧縮を行った後、オブジェクトストレージの使用量が減少するのは、Milvusのガベージコレクションがセーフティウィンドウ経過後に参照されていない大容量オブジェクトデータを削除してからとなります。

TEXT の一般的な用途として、BM25を用いた全文検索が挙げられます。このパターンでは、TEXT フィールドに元のソースコンテンツが格納され、BM25がテキストを分析して、キーワードに基づく一致をランク付けするためのスパースベクトルを生成します。これにより、検索結果として一致したTEXT の値が返され、LLMやエージェントワークフローのコンテキストとして利用できます。 以下の例は、TEXT フィールドをBM25の入力フィールドとして使用する方法を示しています。全文検索の概念やクエリオプションについては、「全文検索」を参照してください。

ステップ 1: TEXT フィールドを含むコレクションを作成する

次の例では、ソースコンテンツ用の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は、content に対してBM25関数を適用することで、内部的にスパースベクトルを生成します。

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関数、スパースベクトルインデックス、および全文検索のクエリ構文に関する詳細については、「全文検索」を参照してください。