メインコンテンツまでスキップ

Dynamic Field

Zilliz Cloud では、dynamic field と呼ばれる特別な機能により、柔軟で進化する構造を持つエンティティを挿入できます。このフィールドは $meta という名前の非表示の JSON フィールドとして実装されており、collection schema で明示的に定義されていないデータ内のフィールドを自動的に保存します。

仕組み

dynamic field が有効になると、Zilliz Cloud は各エンティティに非表示の $meta フィールドを追加します。このフィールドは JSON 型であるため、JSON と互換性のある任意のデータ構造を保存でき、JSON path 構文を使用して index を作成できます。

データ挿入時には、schema で宣言されていないフィールドはすべて、この dynamic field 内にキーと値のペアとして自動的に保存されます。

$meta を手動で管理する必要はありません。Zilliz Cloud が透過的に処理します。

たとえば、collection schema で idvector のみが定義されていて、次のエンティティを挿入したとします。

json
{
"id": 1,
"vector": [0.1, 0.2, 0.3],
"name": "Item A", // Not in schema
"category": "books" // Not in schema
}

dynamic field 機能を有効にすると、Zilliz Cloud は内部的に次のように保存します。

json
{
"id": 1,
"vector": [0.1, 0.2, 0.3],
"$meta": {
"name": "Item A",
"category": "books"
}
}

これにより、schema を変更することなくデータ構造を進化させることができます。

一般的なユースケースには次のようなものがあります。

  • オプションのフィールドや、あまり頻繁に取得しないフィールドの保存

  • エンティティごとに異なる metadata の取り込み

  • 特定の dynamic field キーに対する index を通じた柔軟なフィルタリングのサポート

サポートされるデータ型

dynamic field は、単純な値と複雑な値の両方を含む、Zilliz Cloud が提供するすべての scalar データ型をサポートします。これらのデータ型は、$meta に保存されるキーの値に適用されます。

サポートされる型は次のとおりです。

  • String (VARCHAR)

  • Integer (INT8, INT32, INT64)

  • Floating point (FLOAT, DOUBLE)

  • Boolean (BOOL)

  • scalar 値の配列 (ARRAY)

  • JSON オブジェクト (JSON)

例:

json
{
"brand": "Acme",
"price": 29.99,
"in_stock": true,
"tags": ["new", "hot"],
"specs": {
"weight": "1.2kg",
"dimensions": { "width": 10, "height": 20 }
}
}

上記の各キーと値は $meta フィールド内に保存されます。

dynamic field を有効にする

dynamic field 機能を使用するには、collection schema の作成時に enable_dynamic_field=True を設定します。

python
from pymilvus import MilvusClient, DataType

# Initialize client
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")

# Create schema with dynamic field enabled
schema = client.create_schema(
auto_id=False,
enable_dynamic_field=True,
)

# Add explicitly defined fields
schema.add_field(field_name="my_id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="my_vector", datatype=DataType.FLOAT_VECTOR, dim=5)

# Create the collection
client.create_collection(
collection_name="my_collection",
schema=schema
)

collection に entity を挿入する

dynamic field を使用すると、schema で定義されていない追加フィールドを挿入できます。これらのフィールドは自動的に $meta に保存されます。

python
entities = [
{
"my_id": 1, # Explicitly defined primary field
"my_vector": [0.1, 0.2, 0.3, 0.4, 0.5], # Explicitly defined vector field
"overview": "Great product", # Scalar key not defined in schema
"words": 150, # Scalar key not defined in schema
"dynamic_json": { # JSON key not defined in schema
"varchar": "some text",
"nested": {
"value": 42.5
},
"string_price": "99.99" # Number stored as string
}
}
]

client.insert(collection_name="my_collection", data=entities)

dynamic field 内のキーに index を作成する

Zilliz Cloud では、JSON path indexing を使用して dynamic field 内の特定のキーに index を作成できます。これらは scalar 値にも、JSON オブジェクト内のネストされた値にも対応します。

📘注意

dynamic field のキーへの index 作成は任意です。index がなくても dynamic field のキーで query や filter を実行できますが、総当たり検索になるためパフォーマンスが低下する可能性があります。

JSON path indexing の構文

JSON path index を作成するには、以下を指定します。

  • JSON path (json_path): index を作成したい JSON オブジェクト内のキーまたはネストされたフィールドへのパス。

    • 例: metadata["category"]

      これは、indexing engine が JSON 構造内のどこを参照するかを定義します。

  • JSON cast type (json_cast_type): 指定されたパスの値を解釈して index 化する際に、Zilliz Cloud が使用するデータ型。

    • この型は、index 対象フィールドの実際のデータ型と一致している必要があります。

    • 完全な一覧については、Supported JSON cast types を参照してください。

JSON path を使用して dynamic field のキーに index を作成する

dynamic field は JSON field であるため、JSON path 構文を使ってその中の任意のキーに index を作成できます。これは単純な scalar 値にも、複雑にネストされた構造にも有効です。

JSON path の例:

  • 単純なキー: overview, words

  • ネストされたキー: dynamic_json['varchar'], dynamic_json['nested']['value']

python
index_params = client.prepare_index_params()

# Index a simple string key
index_params.add_index(
field_name="overview", # Key name in the dynamic field
index_type="AUTOINDEX", # Must be set to AUTOINDEX for JSON path indexing
index_name="overview_index", # Unique index name
params={
"json_cast_type": "varchar", # Data type that Zilliz Cloud uses when indexing the values
"json_path": "overview" # JSON path to the key
}
)

# Index a simple numeric key
index_params.add_index(
field_name="words", # Key name in the dynamic field
index_type="AUTOINDEX", # Must be set to AUTOINDEX for JSON path indexing
index_name="words_index", # Unique index name
params={
"json_cast_type": "double", # Data type that Zilliz Cloud uses when indexing the values
"json_path": "words" # JSON path to the key
}
)

# Index a nested key within a JSON object
index_params.add_index(
field_name="dynamic_json", # JSON key name in the dynamic field
index_type="AUTOINDEX", # Must be set to AUTOINDEX for JSON path indexing
index_name="json_varchar_index", # Unique index name
params={
"json_cast_type": "varchar", # Data type that Zilliz Cloud uses when indexing the values
"json_path": "dynamic_json['varchar']" # JSON path to the nested key
}
)

# Index a deeply nested key
index_params.add_index(
field_name="dynamic_json",
index_type="AUTOINDEX", # Must be set to AUTOINDEX for JSON path indexing
index_name="json_nested_index", # Unique index name
params={
"json_cast_type": "double",
"json_path": "dynamic_json['nested']['value']"
}
)

型変換に JSON cast function を使用する

dynamic field のキーに不正な形式の値が含まれている場合(例: 文字列として保存された数値)、cast function を使って変換できます。

python
# Convert a string to double before indexing
index_params.add_index(
field_name="dynamic_json", # JSON key name
index_type="AUTOINDEX",
index_name="json_string_price_index",
params={
"json_path": "dynamic_json['string_price']",
"json_cast_type": "double", # Must be the output type of the cast function
"json_cast_function": "STRING_TO_DOUBLE" # Case insensitive; convert string to double
}
)
📘注意
  • 型変換に失敗した場合(例: 値 "not_a_number" を数値に変換できない場合)、その値はスキップされ、index 化されません。

  • cast function パラメータの詳細については、JSON Field Overview を参照してください。

collection に index を適用する

index パラメータを定義した後、create_index() を使用して collection に適用できます。

python
client.create_index(
collection_name="my_collection",
index_params=index_params
)

dynamic field のキーで filter する

dynamic field のキーを持つ entity を挿入した後は、標準の filter expression を使って filter できます。

  • 非 JSON キー(例: 文字列、数値、ブール値)の場合は、キー名を直接参照できます。

  • JSON オブジェクトを格納しているキーの場合は、JSON path 構文を使用してネストされた値にアクセスします。

前のセクションの example entity に基づくと、有効な filter expression の例は次のとおりです。

python
filter = 'overview == "Great product"' # Non-JSON key
filter = 'words >= 100' # Non-JSON key
filter = 'dynamic_json["nested"]["value"] < 50' # JSON object key

dynamic field キーの取得: 検索または query 結果で dynamic field のキーを返すには、filter と同じ JSON path 構文を使用して output_fields パラメータに明示的に指定する必要があります。

python
# Example: Include dynamic field keys in search results
results = client.search(
collection_name="my_collection",
data=[[0.1, 0.2, 0.3, 0.4, 0.5]],
filter=filter, # Filter expression defined earlier
limit=10,
output_fields=[
"overview", # Simple dynamic field key
"dynamic_json" # Nested JSON key
]
)
📘注意

dynamic field のキーはデフォルトでは結果に含まれないため、明示的に要求する必要があります。

サポートされている演算子と filter expression の完全な一覧については、Filtered Search を参照してください。

まとめ

ここまでで、schema で定義されていないキーを柔軟に保存し、index 化するために dynamic field を使う方法を学びました。dynamic field のキーが一度挿入されると、filter expression 内で他の field と同じように使用できます。特別な構文は必要ありません。

実際のアプリケーションでワークフローを完了するには、さらに次のことも必要です。

  • vector field に index を作成する(各 collection で必須)

    AUTOINDEX Explained と関連ページを参照してください

  • collection を load する

    Load & Release を参照してください

  • JSON path filter を使って search または query を実行する

    Filtered SearchJSON Operators を参照してください

FAQ

dynamic field キーを使う代わりに、いつ field を schema で明示的に定義すべきですか?

次のような場合は、dynamic field キーを使う代わりに field を schema で明示的に定義するべきです。

  • field が頻繁に output_fields に含まれる場合: output_fields を通じて効率的に取得できることが保証されるのは、明示的に定義された field のみです。dynamic field のキーは高頻度の取得向けには最適化されておらず、パフォーマンスオーバーヘッドが発生する可能性があります。

  • field へのアクセスや filter が頻繁な場合: dynamic field キーに index を作成すれば、固定 schema の field と同等の filter パフォーマンスを得られる場合がありますが、明示的な field の方が構造が明確で、保守性も高くなります。

  • field の動作を完全に制御する必要がある場合: 明示的な field は、schema レベルの制約、検証、より明確な型指定をサポートしており、データの整合性や一貫性の管理に役立ちます。

  • index の不整合を避けたい場合: dynamic field キー内のデータは、型や構造の不整合が起きやすくなります。固定 schema を使用することで、特に index や cast を使用する予定がある場合に、データ品質を確保しやすくなります。

dynamic field キーを既存 collection 内の明示的な scalar field にすることを決めた場合は、Alter Collection Schema を参照してください。既存 collection レベルの dynamic field 設定は collection properties を通じて管理されます。詳細は Modify Collection を参照してください。

同じ dynamic field キーに対して、異なるデータ型で複数の index を作成できますか?

いいえ、1 つの JSON path につき作成できる index は 1 つだけです。dynamic field キーに混在する型の値(例: 一部が文字列で一部が数値)が含まれていても、そのパスを index 化する際には単一の json_cast_type を選択する必要があります。同じキーに対して異なる型で複数の index を作成することは、現時点ではサポートされていません。

dynamic field キーを index 化する際、データの cast に失敗した場合はどうなりますか?

dynamic field キーに index を作成していて、データの cast に失敗した場合、たとえば double に cast されるべき値が "abc" のような数値でない文字列だった場合、その値は index 作成時に黙ってスキップされます。それらは index に含まれないため、index に依存する filter ベースの search や query 結果には返されません

この挙動には、いくつか重要な意味があります。

  • フルスキャンへのフォールバックなし: entity の大半が正常に index 化されている場合、filter query は完全に index に依存します。cast に失敗した entity は、論理的には filter 条件に一致していても、結果セットから除外されます。

  • 検索精度へのリスク: 大規模データセットでデータ品質に一貫性がない場合(特に dynamic field キー内)、この挙動により予期しない欠落結果が発生することがあります。index 化の前に、一貫した有効なデータ形式を確保することが重要です。

  • cast function は慎重に使用する: index 作成時に json_cast_function を使用して文字列を数値に変換する場合、その文字列値が確実に変換可能であることを確認してください。json_cast_type と実際に変換された型が一致しないと、エラーやエントリのスキップが発生します。

query で index 作成時の cast type と異なるデータ型を使用すると、どうなりますか?

query が、index で使用された型とは異なるデータ型で dynamic field キーを比較した場合(例: index が double に cast されているのに、文字列比較で query する場合)、システムは index を使用しません。また、可能な場合に限りフルスキャンにフォールバックすることがあります。最適なパフォーマンスと精度を得るには、query の型を index 作成時に使用した json_cast_type に一致させてください。

Ctrl I