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

動的フィールド

Zilliz Cloud では、動的フィールドと呼ばれる特別な機能を使用して、柔軟で進化する構造のエンティティを挿入できます。このフィールドは $meta という名前の非表示の JSON フィールドとして実装され、コレクションスキーマで明示的に定義されていないデータ内のすべてのフィールドを自動的に格納します。

仕組み​

動的フィールドが有効な場合、Zilliz Cloud は各エンティティに非表示の $meta フィールドを追加します。このフィールドは JSON 型であるため、JSON 互換の任意のデータ構造を格納でき、JSON パス構文を使用してインデックスを作成できます。

データ挿入時、スキーマで宣言されていないフィールドは、この動的フィールド内にキーと値のペアとして自動的に格納されます。

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

たとえば、コレクションスキーマで id と vector のみを定義し、次のエンティティを挿入したとします。

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

動的フィールド機能が有効な場合、Zilliz Cloud は次のように内部的に格納します。

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

これにより、スキーマを変更せずにデータ構造を進化させることができます。

一般的なユースケースは次のとおりです。

  • オプションのフィールドや頻繁に取得されないフィールドの格納

  • エンティティごとに異なるメタデータのキャプチャ

  • 特定の動的フィールドキーに対するインデックスによる柔軟なフィルタリングのサポート

サポートされるデータ型​

動的フィールドは、単純な値と複雑な値の両方を含め、Zilliz Cloud が提供するすべてのスカラーデータ型をサポートします。これらのデータ型は、$meta に格納されるキーの値に適用されます。

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

  • 文字列(VARCHAR)

  • 整数(INT8、INT32、INT64)

  • 浮動小数点(FLOAT、DOUBLE)

  • ブール値(BOOL)

  • スカラー値の配列(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 フィールド内に格納されます。

動的フィールドを有効にする​

動的フィールド機能を使用するには、コレクションスキーマの作成時に 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
)

コレクションへのエンティティの挿入​

動的フィールドを使用すると、スキーマで定義されていない追加のフィールドを挿入できます。これらのフィールドは $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)

動的フィールド内のキーのインデックス作成​

Zilliz Cloud では、JSON パスインデックスを使用して、動的フィールド内の特定のキーにインデックスを作成できます。対象となるのは、スカラー値または JSON オブジェクト内のネストされた値です。

Notes

動的フィールドキーのインデックス作成は任意です。インデックスがなくても動的フィールドキーでクエリやフィルタリングを実行できますが、ブルートフォース検索のためパフォーマンスが低下する可能性があります。

JSON パスインデックスの構文​

JSON パスインデックスを作成するには、次を指定します。

  • JSON パス(json_path):インデックスを作成する JSON オブジェクト内のキーまたはネストされたフィールドへのパスです。

    • 例: metadata["category"]

      これは、インデックスエンジンが JSON 構造内のどこを参照するかを定義します。

  • JSON キャスト型(json_cast_type):指定したパスの値を解釈してインデックスを作成する際に、Zilliz Cloud が使用するデータ型です。

    • この型は、インデックスを作成するフィールドの実際のデータ型と一致している必要があります。

    • 完全なリストについては、サポートされる JSON キャスト型 を参照してください。

JSON パスを使用して動的フィールドのキーにインデックスを作成する​

動的フィールドは JSON フィールドであるため、その内部の任意のキーに JSON パス構文を使用してインデックスを作成できます。これは、単純なスカラー値と複雑なネスト構造の両方で機能します。

JSON パスの例:

  • 単純なキーの場合: overview、words

  • ネストされたキーの場合: dynamic_json['varchar']、dynamic_json['nested']['value']

python
index_params = client.prepare_index_params()

# Add a vector index on the vector field so the collection can be loaded
index_params.add_index(
field_name="my_vector",
index_type="AUTOINDEX",
metric_type="COSINE",
)

# 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 キャスト関数を使用した型変換​

動的フィールドキーに正しくない形式の値(たとえば、文字列として格納された数値)が含まれている場合は、キャスト関数を使用して変換できます。

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
}
)
Notes
  • 型変換に失敗した場合(たとえば、値 "not_a_number" を数値に変換できない場合)、その値はスキップされ、インデックスに含まれません。

  • キャスト関数のパラメーターの詳細については、JSON フィールドの概要 を参照してください。

コレクションへのインデックスの適用​

インデックスパラメーターを定義した後、create_index() を使用してコレクションに適用できます。

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

# Load the collection before searching
client.load_collection(collection_name="my_collection")

動的フィールドキーによるフィルタリング​

動的フィールドキーを含むエンティティを挿入した後、標準のフィルター式を使用してそれらをフィルタリングできます。

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

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

前のセクションで示した例エンティティに基づくと、有効なフィルター式には次のものが含まれます。

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

動的フィールドキーの取得:検索またはクエリの結果で動的フィールドキーを返すには、フィルタリングと同じ JSON パス構文を使用して、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
]
)
Notes

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

サポートされる演算子とフィルター式の完全なリストについては、フィルター検索 を参照してください。

まとめ​

ここまでで、動的フィールドを使用して、スキーマで定義されていないキーを柔軟に格納し、インデックスを作成する方法を学びました。動的フィールドキーを挿入した後は、特別な構文を使用せずに、フィルター式で他のフィールドと同様に使用できます。

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

  • ベクトルフィールドにインデックスを作成する(各コレクションで必須)

    詳細については、AUTOINDEX の説明 とその関連ページを参照してください。

  • コレクションをロードする

    詳細については、ロードと解放 を参照してください。

  • JSON パスフィルターを使用して検索またはクエリを実行する

    詳細については、フィルター検索 と JSON 演算子 を参照してください。

FAQ​

動的フィールドキーではなく、スキーマでフィールドを明示的に定義する必要があるのはどのような場合ですか?​

次のいずれかに該当する場合は、動的フィールドキーを使用せず、スキーマでフィールドを明示的に定義してください。

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

  • フィールドが頻繁にアクセスまたはフィルタリングされる場合:動的フィールドキーにインデックスを作成すると、固定スキーマのフィールドと同様のフィルタリングパフォーマンスを得られますが、明示的に定義されたフィールドの方が構造が明確で保守性にも優れています。

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

  • インデックス作成の不整合を避けたい場合:動的フィールドキーのデータは、型や構造が不整合になりやすい傾向があります。固定スキーマを使用すると、特にインデックス作成やキャストの使用を予定している場合に、データ品質を確保しやすくなります。

既存のコレクションで動的フィールドキーを明示的なスカラーフィールドにすることにした場合は、コレクションスキーマの変更 を参照してください。既存のコレクションレベルの動的フィールド設定はコレクションプロパティで管理されます。詳細については、コレクションの変更 を参照してください。

同じ動的フィールドキーに異なるデータ型で複数のインデックスを作成できますか?​

いいえ、JSON パスごとに作成できるインデックスは 1 つだけです。動的フィールドキーに混合型の値(たとえば、文字列と数値)が含まれている場合でも、そのパスにインデックスを作成するときは単一の json_cast_type を選択する必要があります。現時点では、同じキーに異なる型で複数のインデックスを作成することはサポートされていません。

動的フィールドキーにインデックスを作成する際にデータのキャストが失敗した場合はどうなりますか?​

動的フィールドキーにインデックスを作成しており、データのキャストが失敗した場合(たとえば、double にキャストされるはずの値が "abc" のような数値以外の文字列である場合)、それらの値はインデックス作成時に通知されずにスキップされます。これらの値はインデックスに含まれないため、インデックスに依存するフィルターベースの検索またはクエリの結果には返されません。

これには、次のようないくつかの重要な影響があります。

  • フルスキャンへのフォールバックなし:大多数のエンティティのインデックス作成が成功した場合、フィルタリングクエリはインデックスに完全に依存します。キャストに失敗したエンティティは、論理的にフィルター条件に一致する場合でも、結果セットから除外されます。

  • 検索精度のリスク:データ品質が一貫していない大規模なデータセット(特に動的フィールドキー)では、この動作により予期しない結果の欠落が発生する可能性があります。インデックスを作成する前に、一貫性のある有効なデータ形式を確保することが重要です。

  • キャスト関数は慎重に使用する:インデックス作成中に json_cast_function を使用して文字列を数値に変換する場合は、文字列の値を確実に変換できることを確認してください。json_cast_type と実際に変換された型が一致しない場合、エラーが発生したりエントリがスキップされたりします。

クエリで、インデックスに使用されたキャスト型とは異なるデータ型を使用した場合はどうなりますか?​

クエリで、インデックスに使用された型とは異なるデータ型を使用して動的フィールドキーを比較する場合(たとえば、インデックスが double にキャストされているのに文字列比較でクエリする場合)、システムはインデックスを使用せず、可能な場合に限りフルスキャンにフォールバックすることがあります。最高のパフォーマンスと精度を得るには、クエリの型がインデックス作成時に使用した json_cast_type と一致していることを確認してください。