メインコンテンツまでスキップ
バージョン: User Guides (Cloud)

既存のコレクションにフィールドを追加

Milvusでは、既存のコレクションに新しいフィールドを動的に追加することができ、アプリケーションのニーズに応じてデータスキーマを容易に変更できます。このガイドでは、実際の例を使用してさまざまなシナリオでフィールドを追加する方法を説明します。

考慮事項

コレクションにフィールドを追加する前に、以下の重要な点を考慮してください:

  • スカラーフィールド(INT64VARCHARFLOATDOUBLEなど)を追加できます。ベクトルフィールドは既存のコレクションに追加することはできません。

  • 新しいフィールドには新しいフィールドの値を持っていない既存のエンティティに対応するため、nullable(nullable=True)である必要があります。

  • 読み込まれたコレクションにフィールドを追加すると、メモリ使用量が増加します。

  • 1つのコレクションあたりのフィールド数には最大制限があります。詳細はMilvus Limitsを参照してください。

  • フィールド名は静的フィールド内で一意である必要があります。

  • 元からenable_dynamic_field=Trueで作成されていないコレクションに、動的フィールド機能を有効にするために$metaフィールドを追加することはできません。

前提条件

このガイドでは、以下があることを前提としています:

  • 実行中のMilvusインスタンス

  • Milvus SDKがインストールされている

  • 既存のコレクション

📘**セットアップが必要ですか?**

コレクションの作成と基本操作については、Create Collectionを参照してください。

基本的な使用方法

from pymilvus import MilvusClient, DataType

# Milvusサーバーに接続
client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT" # MilvusサーバーURIに置き換えてください
)

シナリオ1:nullableフィールドを素早く追加

コレクションを拡張する最も簡単な方法は、nullableフィールドを追加することです。これはデータに新しい属性を素早く追加する必要がある場合に最適です。

# 既存のコレクションにnullableフィールドを追加
# この操作:
# - 即座に返る(非ブロッキング)
# - 最小限の遅延でフィールドを使用可能にする
# - 既存のすべてのエンティティにNULLを設定
client.add_collection_field(
collection_name="product_catalog",
field_name="created_timestamp", # 追加する新しいフィールドの名前
data_type=DataType.INT64, # データ型はスカラー型である必要があります
nullable=True # 追加されたフィールドに対してTrueでなければなりません
# 既存のエンティティにNULL値を許可
)

期待される動作:

  • 既存のエンティティは新しいフィールドにNULLを持つ

  • 新しいエンティティはNULLまたは実際の値を持つことができる

  • フィールドの使用可能性は内部スキーマ同期による最小限の遅延でほぼ即座に発生する

  • クエリ可能なのは短い同期期間の後ですぐに

# クエリ結果の例
{
'id': 1,
'created_timestamp': None # 既存のエンティティの新しいフィールドにNULLを表示
}

シナリオ2:デフォルト値を持つフィールドを追加

既存のエンティティにNULLではなく意味のある初期値を設定したい場合は、デフォルト値を指定します。

# デフォルト値を持つフィールドを追加
# この操作:
# - 既存のすべてのエンティティにデフォルト値を設定
# - 最小限の遅延でフィールドを使用可能にする
# - デフォルト値によるデータ整合性を維持
client.add_collection_field(
collection_name="product_catalog",
field_name="priority_level", # 新しいフィールドの名前
data_type=DataType.VARCHAR, # 文字列型フィールド
max_length=20, # 最大文字列長
nullable=True, # 追加されたフィールドに必須
default_value="standard" # 既存のエンティティに割り当てられる値
# 値が提供されない場合の新しいエンティティにも使用
)

期待される動作:

  • 既存のエンティティは新しく追加されたフィールドにデフォルト値("standard")を持つ

  • 新しいエンティティはデフォルト値を上書きするか、値が提供されない場合はそれを使用できます

  • フィールドの使用可能性は内部スキーマ同期による最小限の遅延でほぼ即座に発生する

  • クエリ可能なのは短い同期期間の後ですぐに

# クエリ結果の例
{
'id': 1,
'priority_level': 'standard' # 既存のエンティティにデフォルト値を表示
}

FAQ

$metaフィールドを追加して動的スキーマ機能を有効にすることはできますか?

いいえ、add_collection_fieldを使用して$metaフィールドを追加して動的フィールド機能を有効にすることはできません。たとえば、以下のコードは機能しません。

# ❌ サポートされていません
client.add_collection_field(
collection_name="existing_collection",
field_name="$meta",
data_type=DataType.JSON # この操作は失敗します
)

動的スキーマ機能を有効にするには:

  • 新しいコレクション:コレクション作成時にenable_dynamic_fieldをTrueに設定します。詳細についてはCreate Collectionを参照してください。

  • 既存のコレクション:コレクションレベルのプロパティdynamicfield.enabledをTrueに設定します。詳細についてはModify Collectionを参照してください。

同じ名前の動的フィールドキーを持つフィールドを追加するとどうなりますか?

コレクションに動的フィールドが有効($metaが存在)になっている場合、既存の動的フィールドキーと同じ名前の静的フィールドを追加できます。新しい静的フィールドは動的フィールドキーをマスクしますが、元の動的データは保持されます。

フィールド名での競合を回避するには、実際に追加する前に既存のフィールドと動的フィールドキーを参照してフィールド名を検討してください。

例のシナリオ:

# 動的フィールドが有効な元のコレクション
# 動的フィールドキーでデータを挿入
data = [{
"id": 1,
"my_vector": [0.1, 0.2, ...],
"extra_info": "this is a dynamic field key", # 文字列としての動的フィールドキー
"score": 99.5 # 別の動的フィールドキー
}]
client.insert(collection_name="product_catalog", data=data)

# 既存の動的フィールドキーと同じ名前の静的フィールドを追加
client.add_collection_field(
collection_name="product_catalog",
field_name="extra_info", # 動的フィールドキーと同じ名前
data_type=DataType.INT64, # データ型は動的フィールドキーと異なる可能性あり
nullable=True # 追加されたフィールドに対してTrueでなければなりません
)

# 静的フィールド追加後の新しいデータを挿入
new_data = [{
"id": 2,
"my_vector": [0.3, 0.4, ...],
"extra_info": 100, # 今やINT64型を使用する必要があります(静的フィールド)
"score": 88.0 # 依然として動的フィールドキー
}]
client.insert(collection_name="product_catalog", data=new_data)

期待される動作:

  • 既存のエンティティは新しい静的フィールドextra_infoにNULLを持つ

  • 新しいエンティティは静的フィールドのデータ型(INT64)を使用しなければならない

  • 元の動的フィールドキー値は保持され、$meta構文でアクセス可能

  • 静的フィールドは通常のクエリで動的フィールドキーをマスク

静的および動的値の両方へのアクセス:

# 1. 静的フィールドのみをクエリ(動的フィールドキーはマスクされる)
results = client.query(
collection_name="product_catalog",
filter="id == 1",
output_fields=["extra_info"]
)
# 返り値: {"id": 1, "extra_info": None} # 既存エンティティのNULL

# 2. 静的および元の動的値の両方をクエリ
results = client.query(
collection_name="product_catalog",
filter="id == 1",
output_fields=["extra_info", "$meta['extra_info']"]
)
# 返り値: {
# "id": 1,
# "extra_info": None, # 静的フィールド値(NULL)
# "$meta['extra_info']": "this is a dynamic field key" # 元の動的値
# }

# 3. 静的フィールド値を持つ新しいエンティティをクエリ
results = client.query(
collection_name="product_catalog",
filter="id == 2",
output_fields=["extra_info"]
)
# 返り値: {"id": 2, "extra_info": 100} # 静的フィールド値

新しいフィールドが使用可能になるまでどれくらいかかりますか?

追加されたフィールドはほぼ即座に使用可能になりますが、Milvusクラスター全体にわたる内部スキーマ変更のブロードキャストによる短い遅延が発生する可能性があります。この同期により、新しいフィールドを含むクエリを処理する前にすべてのノードがスキーマ更新を認識していることを確実にします。