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

動的フィールド

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 と一致することを確認してください。