JSON フィールドの概要
商品カタログ、コンテンツ管理システム、ユーザープリファレンスエンジンなどのアプリケーションを構築する際、ベクトル埋め込みデータとともに柔軟なメタデータを保存する必要がよくあります。商品属性はカテゴリごとに異なり、ユーザーの好みは時間とともに変化し、ドキュメントのプロパティは複雑な入れ子構造を持つことがあります。Zilliz Cloud の JSON フィールドは、このような課題を解決します。柔軟な構造化データをパフォーマンスを犠牲にすることなく保存・クエリできるようにします。
JSON フィールドとは?
JSON フィールドとは、Zilliz Cloud におけるスキーマ定義済みのデータ型(データType.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 は単一の JSON フィールドであり、フラットな値(例: category、in_stock)、配列(tags)、およびネストされたオブジェクト(supplier)が混在しています。
命名規則: JSON キーには文字、数字、アンダースコアのみを使用してください。特殊文字、スペース、ドットはクエリでの解析問題を引き起こす可能性があるため、避けてください。
JSON フィールドと動的フィールド
よく混乱されるポイントとして、JSON フィールドと 動的フィールド の違いがあります。両方とも JSON に関連していますが、目的が異なります。
以下の表は、JSON フィールドと動的フィールドの主な違いをまとめたものです。
機能 | JSON フィールド | 動的フィールド |
|---|---|---|
スキーマ定義 | コレクションスキーマで | 宣言されていないフィールドを自動的に格納する隠し JSON フィールド( |
ユースケース | スキーマが既知で一貫している構造化データを格納する。 | 固定スキーマに適合しない柔軟で進化する、または半構造化のデータを格納する。 |
制御 | フィールド名と構造を自分で制御する。 | 未定義のフィールドはシステムが管理する。 |
クエリ | JSON フィールド内のフィールド名または対象キーを使用してクエリする: | 動的フィールドキーを直接使用してクエリする: |
基本操作
JSON フィールドを使用するための基本的なワークフローは、スキーマで定義し、データを挿入し、特定のフィルタ式を使用してデータをクエリすることです。
JSON フィールドの定義
JSON フィールドを使用するには、コレクション作成時にコレクションスキーマで明示的に定義します。以下の例は、データType.JSON 型の metadata フィールドを持つコレクションを作成する方法を示しています。
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient, DataType
CLUSTER_ENDPOINT = "YOUR_CLUSTER_ENDPOINT"
TOKEN = "YOUR_CLUSTER_TOKEN"
# Set up a Milvus client
client = MilvusClient(
uri=CLUSTER_ENDPOINT,
token=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
)
// java
// js
// go
# restful
この例では、コレクションスキーマで定義されたJSONフィールドが nullable=True により NULL許容 値を許可しています。詳細については、NULL許容 & デフォルト を参照してください。
Insert data
コレクションが作成されたら、指定したJSONフィールドに構造化されたJSONオブジェクトを含むエンティティを挿入します。データは辞書のリストとしてフォーマットする必要があります。
- Python
- Java
- NodeJS
- Go
- cURL
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)
// java
// js
// go
# restful
フィルタリング操作
JSONフィールドに対してフィルタリング操作を実行する前に、以下の点を確認してください:
-
各ベクトルフィールドにインデックスを作成済みであること。
-
コレクションがメモリにロード済みであること。
コード例を表示
- Python
- Java
- NodeJS
- Go
- cURL
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")
// java
// js
// go
# restful
これらの要件を満たせば、JSONフィールド内の値に基づいてコレクションをフィルタリングするための以下の式を使用できます。これらのフィルター式は、特定のJSONパス構文と専用の演算子を活用します。
JSONパス構文によるフィルタリング
特定のキーをクエリするには、角括弧表記を使用してJSONキーにアクセスします:json_field_name["key"]。ネストされたキーの場合は、それらを連鎖させます:json_field_name["key1"]["key2"]。
categoryが"electronics"であるエンティティをフィルタリングするには:
- Python
- Java
- NodeJS
- Go
- cURL
# 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
)
// java
// js
// go
# restful
ネストされたキー supplier["country"] が "USA" であるエンティティをフィルタリングするには:
- Python
- Java
- NodeJS
- Go
- cURL
# 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)
// java
// js
// go
# restful
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
- Java
- NodeJS
- Go
- cURL
# 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)
// java
// js
// go
# restful
tags キーの下に "electronics"、"new"、または "clearance" のいずれか少なくとも 1 つの値を持つ製品を検索するには:
- Python
- Java
- NodeJS
- Go
- cURL
# 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)
// java
// js
// go
# restful
JSON固有の演算子の詳細については、JSON演算子 を参照してください。
Next: JSONクエリの高速化
デフォルトでは、高速化なしでJSONフィールドに対するクエリを実行すると、すべての行のフルスキャンが行われ、大規模なデータセットでは遅くなる可能性があります。JSONクエリを高速化するために、Zilliz Cloud は高度なインデックス作成とストレージ最適化機能を提供しています。
以下の表に、それらの違いと最適な使用シナリオをまとめます:
手法 | 最適な用途 | 配列の高速化 | 備考 |
|---|---|---|---|
JSONインデックス | 頻繁にアクセスされる少数のキー、特定の配列キー上の配列 | はい(インデックス付き配列キー上) | キーを事前に選択する必要があり、スキーマが進化する場合はメンテナンスが必要 |
JSONシュレッディング | 多くのキー全体の一般的な高速化、様々なクエリに柔軟に対応 | はい(総当たりクエリと比較して配列値をやや高速化) | 追加のストレージ設定、配列には引き続きキーごとのインデックスが必要 |
NGRAMインデックス | ワイルドカード検索、テキストフィールドでの部分文字列マッチング | 該当なし | 数値/範囲フィルタには非対応 |
ヒント: これらのアプローチを組み合わせることができます。例えば、広範なクエリ高速化にはJSONシュレッディングを、高頻度の配列キーにはJSONインデックス作成を、柔軟なテキスト検索にはNGRAMインデックス作成を使用します。
実装の詳細については、以下を参照してください:
FAQ
JSONフィールドのサイズに制限はありますか?
はい。各JSONフィールドは65,536バイトに制限されています。
JSONフィールドはデフォルト値の設定をサポートしていますか?
いいえ、JSONフィールドはデフォルト値をサポートしていません。ただし、フィールド定義時に nullable=True を設定して、空のエントリを許可することはできます。
詳細については、NULL許容 & デフォルト を参照してください。
JSONフィールドのキーに命名規則はありますか?
はい、クエリとインデックス作成との互換性を確保するために:
-
JSONキーには、文字、数字、アンダースコアのみを使用してください。
-
特殊文字、スペース、ドット(
.、/など)の使用は避けてください。 -
互換性のないキーは、フィルタ式の解析で問題を引き起こす可能性があります。
Zilliz Cloud はJSONフィールドの文字列値をどのように処理しますか?
Zilliz Cloud は、JSON入力に表示されているとおりに文字列値を正確に保存します—意味的な変換は行われません。不適切に引用符で囲まれた文字列は、解析時にエラーが発生する可能性があります。
有効な文字列の例:
"a\"b", "a'b", "a\\b"
無効な文字列の例:
'a"b', 'a\'b'