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

JSON フィールドの概要

商品カタログ、コンテンツ管理システム、ユーザー嗜好エンジンなどのアプリケーションを構築する際、ベクトル埋め込みと併せて柔軟なメタデータを保存する必要がよくあります。商品属性はカテゴリごとに異なり、ユーザーの嗜好は時間とともに変化し、ドキュメントのプロパティには複雑なネスト構造があります。Zilliz Cloud の JSON フィールドは、パフォーマンスを犠牲にすることなく、柔軟な構造化データを保存してクエリできるようにすることで、この課題を解決します。

JSON フィールドとは?​

JSON フィールドは、Zilliz Cloud のスキーマ定義済みデータ型(DataType.JSON)で、構造化されたキーと値のデータを保存します。従来の固定されたデータベース列とは異なり、JSON フィールドはネストされたオブジェクト、配列、混在したデータ型に対応し、高速なクエリのための複数のインデックス作成オプションを提供します。

JSON フィールドの構造例:

json
{
"metadata": {
"category": "electronics",
"brand": "BrandA",
"in_stock": true,
"price": 99.99,
"string_price": "99.99",
"tags": ["clearance", "summer_sale"],
"supplier": {
"name": "SupplierX",
"country": "USA",
"contact": {
"email": "support@supplierx.com",
"phone": "+1-800-555-0199"
}
}
}
}

この例では、metadata はフラットな値(例: category、in_stock)、配列(tags)、ネストされたオブジェクト(supplier)を組み合わせて含む単一の JSON フィールドです。

📘Notes

命名規則: JSON キーには英字、数字、アンダースコアのみを使用してください。特殊文字、スペース、ドットはクエリの解析問題を引き起こす可能性があるため、使用しないでください。

JSON フィールドと動的フィールド​

JSON フィールドと 動的フィールド の違いは、よく混乱される点です。どちらも JSON に関連していますが、目的は異なります。

次の表は、JSON フィールドと動的フィールドの主な違いをまとめたものです:

機能

JSON フィールド

動的フィールド

スキーマ定義

コレクションスキーマで DataType.JSON 型として明示的に宣言する必要があるスカラーフィールドです。

宣言されていないフィールドを自動的に保存する隠し JSON フィールド($meta という名前)です。

ユースケース

スキーマが既知で一貫している構造化データを保存します。

固定スキーマに適合しない、柔軟で進化するデータや半構造化データを保存します。

制御

フィールド名と構造はユーザーが制御します。

未定義のフィールドはシステムによって管理されます。

クエリ

JSON フィールド内のフィールド名または対象キー(metadata["key"])を使用してクエリします。

動的フィールドキー("dynamic_key")を使用するか、meta</code>経由(<code>meta</code> 経由(<code>meta["dynamic_key"])で直接クエリします。

基本的な操作​

JSON フィールドを使用する基本的なワークフローは、スキーマで定義し、データを挿入してから、特定のフィルター式を使用してデータをクエリするという流れです。

JSON フィールドを定義する​

JSON フィールドを使用するには、コレクションの作成時にコレクションスキーマで明示的に定義します。次の例は、DataType.JSON 型の metadata フィールドを持つコレクションを作成する方法を示しています:

python
from pymilvus import MilvusClient, DataType

client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT", token="YOUR_CLUSTER_TOKEN")

# Create schema
schema = client.create_schema(auto_id=False, enable_dynamic_field=True)

schema.add_field(field_name="product_id", datatype=DataType.INT64, is_primary=True) # Primary field
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5) # Vector field
# Define a JSON field that allows null values
schema.add_field(field_name="metadata", datatype=DataType.JSON, nullable=True)

client.create_collection(
collection_name="product_catalog",
schema=schema
)
📘Notes

この例では、コレクションスキーマで定義された JSON フィールドは、nullable=True により null 値を許可します。詳細は、Nullable & Default を参照してください。

データを挿入する​

コレクションを作成したら、指定した JSON フィールドに構造化 JSON オブジェクトを含むエンティティを挿入します。データはディクショナリのリストとしてフォーマットする必要があります。

python
entities = [
{
"product_id": 1,
"vector": [0.1, 0.2, 0.3, 0.4, 0.5],
"metadata": { # JSON field
"category": "electronics",
"brand": "BrandA",
"in_stock": True,
"price": 99.99,
"string_price": "99.99",
"tags": ["clearance", "summer_sale"],
"supplier": {
"name": "SupplierX",
"country": "USA",
"contact": {
"email": "support@supplierx.com",
"phone": "+1-800-555-0199"
}
}
}
}
]

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

フィルタリング操作​

JSON フィールドでフィルタリング操作を実行する前に、次のことを確認してください:

  • 各ベクトルフィールドにインデックスを作成していること。

  • コレクションがメモリにロードされていること。

Show code
python
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector",
index_type="AUTOINDEX",
index_name="vector_index",
metric_type="COSINE"
)

client.create_index(collection_name="product_catalog", index_params=index_params)

client.load_collection(collection_name="product_catalog")

これらの要件を満たしたら、以下の式を使用して、JSON フィールド内の値に基づいてコレクションをフィルタリングできます。これらのフィルター式は、特定の JSON パス構文と専用の演算子を利用します。

JSON パス構文によるフィルタリング​

特定のキーをクエリするには、ブラケット記法を使用して JSON キーにアクセスします: json_field_name["key"]。ネストされたキーの場合は、json_field_name["key1"]["key2"] のように連結します。

category が "electronics" であるエンティティをフィルタリングするには:

python
# Define filter expression
filter = 'metadata["category"] == "electronics"'

client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)

ネストされたキー supplier["country"] が "USA" であるエンティティをフィルタリングするには:

python
# Define filter expression
filter = 'metadata["supplier"]["country"] == "USA"'

res = client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)

print(res)

JSON 固有の演算子によるフィルタリング​

Zilliz Cloud では、特定の JSON フィールドキーで配列値をクエリするための特別な演算子も提供しています。例:

  • json_contains(identifier, expr): JSON 配列内に特定の要素またはサブ配列が存在するかどうかを確認します。

  • json_contains_all(identifier, expr): 指定した JSON 式のすべての要素がフィールドに存在することを確認します。

  • json_contains_any(identifier, expr): JSON 式の少なくとも 1 つのメンバーがフィールド内に存在するエンティティをフィルタリングします。

tags キーの下に "summer_sale" 値を持つ商品を検索するには:

python
# Define filter expression
filter = 'json_contains(metadata["tags"], "summer_sale")'

res = client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)

print(res)

tags キーの下に "electronics"、"new"、"clearance" のいずれかの値を持つ商品を検索するには:

python
# Define filter expression
filter = 'json_contains_any(metadata["tags"], ["electronics", "new", "clearance"])'

res = client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)

print(res)

JSON 固有の演算子の詳細は、JSON Operators を参照してください。

次に: JSON クエリを高速化する​

デフォルトでは、高速化されていない JSON フィールドに対するクエリはすべての行のフルスキャンを実行するため、大規模なデータセットでは遅くなる可能性があります。JSON クエリを高速化するために、Zilliz Cloud は高度なインデックス作成機能とストレージ最適化機能を提供しています。

🚧Warning

Milvus 3.0.0 以降、JSON フラットインデックスとも呼ばれるオブジェクト全体の JSON インデックス(json_cast_type="JSON")は非推奨です。既存のインデックスと新しいインデックス作成リクエストは互換性のために引き続きサポートされますが、このモードは新しいワークロードには推奨されません。既知のクエリパスには JSON パスインデックスを使用するか、複雑または進化するドキュメント全体の幅広いクエリ高速化には JSON Shredding を検討してください。

次の表は、それぞれの違いと最適なユースケースをまとめたものです:

手法

最適な用途

配列の高速化

注記

JSON インデックス

頻繁にアクセスされる少数のキー、特定の配列キー上の配列

はい(インデックス付き配列キー上)

キーを事前に選択する必要があり、スキーマが進化した場合はメンテナンスが必要です

JSON Shredding

多くのキーにわたる一般的な高速化、さまざまなクエリへの柔軟な対応

いいえ(配列内の値は高速化されません)

追加のストレージ設定が必要で、配列には引き続きキーごとのインデックスが必要です

NGRAM インデックス

ワイルドカード検索、テキストフィールド内の部分文字列一致

N/A

numeric/range フィルターには使用できません

ヒント: これらのアプローチは組み合わせることができます。たとえば、幅広いクエリ高速化には JSON Shredding、高頻度の配列キーには JSON インデックス、柔軟なテキスト検索には NGRAM インデックスを使用します。

実装の詳細は、次を参照してください:

よくある質問​

JSON フィールドのサイズに制限はありますか?​

はい。各 JSON フィールドは 65,536 バイトに制限されています。

JSON フィールドはデフォルト値の設定をサポートしていますか?​

いいえ、JSON フィールドはデフォルト値をサポートしていません。ただし、フィールドの定義時に nullable=True を設定すると、空のエントリを許可できます。

詳細は、Nullable & Default を参照してください。

JSON フィールドのキーに命名規則はありますか?​

はい。クエリおよびインデックス作成との互換性を確保するには、次のようにします:

  • JSON キーには英字、数字、アンダースコアのみを使用します。

  • 特殊文字、スペース、ドット(.、/ など)の使用は避けます。

  • 互換性のないキーは、フィルター式の解析問題を引き起こす可能性があります。

Zilliz Cloud は JSON フィールドの文字列値をどのように処理しますか?​

Zilliz Cloud は文字列値を、JSON 入力に現れるとおりに、意味的な変換を行わずに保存します。引用符が不適切な文字列は、解析中にエラーになる可能性があります。

有効な文字列の例:

plaintext
"a\"b", "a'b", "a\\b"

無効な文字列の例:

plaintext
'a"b', 'a\'b'