JSONフィールド
Milvusでは、JSON データ型を使用して、構造化されたデータを単一のフィールド内に格納し、インデックスを作成することができます。これにより、JSONインデックスによる効率的なフィルタリングを可能にしながら、ネストされた属性を持つ柔軟なスキーマが可能になります。
JSONフィールドとは何ですか?
JSONフィールドはMilvusのスキーマ定義フィールドで、構造化されたキーバリューのデータを格納します。値には、文字列、数値、ブーリアン、配列、または深くネストされたオブジェクトを含めることができます。
以下は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 フィールドを使用するには、コレクションスキーマでDataType をJSON のように指定して明示的に定義します。
以下の例では、これらのフィールドを含むスキーマでコレクションを作成します:
主キー (
product_id)vectorフィールド(各コレクションに必須)フラット値、配列、ネストされたオブジェクトのような構造化データを格納できる
JSON型のmetadataフィールド。
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="http://localhost:19530")
# Create schema with a JSON field
schema = client.create_schema(auto_id=False, enable_dynamic_field=True)
schema.add_field(field_name="product_id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5)
schema.add_field(field_name="metadata", datatype=DataType.JSON, nullable=True) # JSON field that allows null values
client.create_collection(
collection_name="product_catalog",
schema=schema
)
import io.milvus.v2.client.*;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.collection.request.AddFieldReq;
ConnectConfig config = ConnectConfig.builder()
.uri("http://localhost:19530")
.build();
MilvusClientV2 client = new MilvusClientV2(config);
CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder()
.enableDynamicField(true)
.build();
schema.addField(AddFieldReq.builder()
.fieldName("product_id")
.dataType(DataType.Int64)
.isPrimaryKey(Boolean.TRUE)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("metadata")
.dataType(DataType.JSON)
.isNullable(true)
.build());
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("product_catalog")
.collectionSchema(schema)
.build();
client.createCollection(requestCreate);
import { MilvusClient, DataType } from '@zilliz/milvus2-sdk-node';
const client = new MilvusClient({
address: 'localhost:19530'
});
// Create collection
await client.createCollection({
collection_name: "product_catalog",
fields: [
{
name: "product_id",
data_type: DataType.Int64,
is_primary_key: true,
autoID: false
},
{
name: "vector",
data_type: DataType.FloatVector,
dim: 5
},
{
name: "metadata",
data_type: DataType.JSON,
nullable: true // JSON field that allows null values
}
],
enable_dynamic_field: true
});
import (
"context"
"github.com/milvus-io/milvus/client/v2/entity"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "localhost:19530",
})
if err != nil {
return err
}
schema := entity.NewSchema().WithDynamicFieldEnabled(true)
schema.WithField(entity.NewField().
WithName("product_id").pk
WithDataType(entity.FieldTypeInt64).
WithIsPrimaryKey(true),
).WithField(entity.NewField().
WithName("vector").
WithDataType(entity.FieldTypeFloatVector).
WithDim(5),
).WithField(entity.NewField().
WithName("metadata").
WithDataType(entity.FieldTypeJSON).
WithNullable(true),
)
err = client.CreateCollection(ctx, milvusclient.NewCreateCollectionOption("product_catalog", schema))
if err != nil {
return err
}
# restful
export TOKEN="root:Milvus"
export CLUSTER_ENDPOINT="http://localhost:19530"
# 字段定义
export productIdField='{
"fieldName": "product_id",
"dataType": "Int64",
"isPrimary": true,
"autoID": false
}'
export vectorField='{
"fieldName": "vector",
"dataType": "FloatVector",
"typeParams": {
"dim": 5
}
}'
export metadataField='{
"fieldName": "metadata",
"dataType": "JSON",
"isNullable": true
}'
# 构造 schema
export schema="{
\"autoID\": false,
\"enableDynamicField\": true,
\"fields\": [
$productIdField,
$vectorField,
$metadataField
]
}"
# 创建集合
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data "{
\"collectionName\": \"product_catalog\",
\"schema\": $schema
}"
宣言されていないフィールドを柔軟に格納するために、ダイナミック・フィールド機能を有効にすることもできますが、JSONフィールドが機能するためには必須ではありません。詳細については、ダイナミック・フィールドを参照してください。
JSON データを持つエンティティの挿入
コレクションが作成されたら、metadata JSONフィールドに構造化JSONオブジェクトを含むエンティティを挿入する。
entities = [
{
"product_id": 1,
"vector": [0.1, 0.2, 0.3, 0.4, 0.5],
"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"
}
}
}
}
]
client.insert(collection_name="product_catalog", data=entities)
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.service.vector.request.InsertReq;
Gson gson = new Gson();
JsonObject row = new JsonObject();
row.addProperty("product_id", 1);
row.add("vector", gson.toJsonTree(Arrays.asList(0.1, 0.2, 0.3, 0.4, 0.5)));
JsonObject metadata = new JsonObject();
metadata.addProperty("category", "electronics");
metadata.addProperty("brand", "BrandA");
metadata.addProperty("in_stock", true);
metadata.addProperty("price", 99.99);
metadata.addProperty("string_price", "99.99");
metadata.add("tags", gson.toJsonTree(Arrays.asList("clearance", "summer_sale")));
JsonObject supplier = new JsonObject();
supplier.addProperty("name", "SupplierX");
supplier.addProperty("country", "USA");
JsonObject contact = new JsonObject();
contact.addProperty("email", "support@supplierx.com");
contact.addProperty("phone", "+1-800-555-0199");
supplier.add("contact", contact);
metadata.add("supplier", supplier);
row.add("metadata", metadata);
client.insert(InsertReq.builder()
.collectionName("product_catalog")
.data(Collections.singletonList(row))
.build());
const entities = [
{
"product_id": 1,
"vector": [0.1, 0.2, 0.3, 0.4, 0.5],
"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"
}
}
}
}
]
await client.insert({
collection_name: "product_catalog",
data: entities
});
_, err = client.Insert(ctx, milvusclient.NewColumnBasedInsertOption("product_catalog").
WithInt64Column("product_id", []int64{1}).
WithFloatVectorColumn("vector", 5, [][]float32{
{0.1, 0.2, 0.3, 0.4, 0.5},
}).WithColumns(
column.NewColumnJSONBytes("metadata", [][]byte{
[]byte(`{
"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"
}
}
}`),
}),
))
if err != nil {
return err
}
# restful
export TOKEN="root:Milvus"
export CLUSTER_ENDPOINT="http://localhost:19530"
export entities='[
{
"product_id": 1,
"vector": [0.1, 0.2, 0.3, 0.4, 0.5],
"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"
}
}
}
}
]'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/product_catalog/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data "{
\"data\": $entities
}"
JSONフィールド内のインデックス値
JSONフィールドのスカラーフィルタリングを高速化するために、Milvusは以下のタイプのインデックスをサポートしています:
JSONパスインデックス- 宣言されたスカラータイプで特定のJSONパスをインデックスします。
JSONフラットインデックス- 自動型推論でJSONオブジェクト全体(またはサブツリー)にインデックスを付けます。
JSONフィールドのインデックスはオプションです。インデックスなしでも JSON パスによるクエリやフィルタリングは可能ですが、総当たり検索になるためパフォーマンスが低下する可能性があります。
パスインデックスとフラットインデックスのどちらかを選択Compatible with Milvus 2.6.x
機能 |
JSONパスインデックス |
JSONフラットインデックス |
|---|---|---|
インデックス対象 |
指定した特定のパス |
オブジェクトパスの下にあるすべてのフラット化されたパス |
型の取り扱い |
|
JSONでなければならない(自動型推論) |
LHSとしての配列¹。 |
サポート |
サポートされていない |
クエリー速度 |
インデックス付きパスでは高速 |
高いが、平均するとやや低い |
ディスク使用量 |
低い |
高い |
¹LHSとしての配列は、フィルター式の左辺がJSON配列であることを意味する:
metadata["tags"] == ["clearance", "summer_sale"]
json_contains(metadata["tags"], "clearance")
これらの場合、metadata["tags"] は配列である。JSONフラットインデックスでは、このようなフィルターは高速化されません。代わりに、配列のキャスト型を持つJSONパスインデックスを使用してください。
JSON パスインデックスは、次のような場合に使用します:
クエリするホットキーを事前に知っている。
左辺が配列であるフィルタを行う必要がある。
ディスク使用量を最小限に抑えたい。
JSONフラットインデックスを使用する場合:
サブツリー全体(ルートを含む)にインデックスを付けたい。
JSON構造が頻繁に変更される。
すべてのパスを宣言せずに、より広範なクエリーをカバーしたい場合。
JSON パスインデックス
JSONパスインデックスを作成するには、次のように指定します:
JSON パス(
json_path):インデックスを作成したい JSON オブジェクト内のキーまたはネストされたフィールドへのパス。例
キーの場合、
metadata["category"]入れ子フィールドの場合、
metadata["contact"]["email"]
これは、インデックス作成エンジンがJSON構造内のどこを探すべきかを定義します。
JSONキャストタイプ(
json_cast_type):Milvusが指定されたパスの値を解釈し、インデックスを作成する際に使用するデータ型。この型は、インデックスされるフィールドの実際のデータ型と一致しなければなりません。インデックス作成中にデータ型を別のものに変換したい場合は、キャスト関数の使用を検討してください。
完全なリストについては、以下を参照してください。
サポートされるJSONキャスト型
キャスト型は大文字と小文字を区別しません。以下の型がサポートされています:
キャスト型 |
説明 |
JSON 値の例 |
|---|---|---|
|
ブール値 |
|
|
数値(整数または浮動小数点数) |
|
|
文字列値 |
|
|
ブール値の配列 |
|
|
数値の配列 |
|
|
文字列の配列 |
|
配列は、最適なインデックス作成のために、同じ型の要素を含むべきである。詳細は「配列フィールド」を参照。
例JSONパス・インデックスの作成
metadata JSON構造を使って、異なるJSONパスにインデックスを作成する例を示します:
# Index the category field as a string
index_params = client.prepare_index_params()
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX", # Must be set to AUTOINDEX or INVERTED for JSON path indexing
index_name="category_index", # Unique index name
params={
"json_path": "metadata[\"category\"]", # Path to the JSON key to be indexed
"json_cast_type": "varchar" # Data cast type
}
)
# Index the tags array as string array
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX", # Must be set to AUTOINDEX or INVERTED for JSON path indexing
index_name="tags_array_index", # Unique index name
params={
"json_path": "metadata[\"tags\"]", # Path to the JSON key to be indexed
"json_cast_type": "array_varchar" # Data cast type
}
)
import io.milvus.v2.common.IndexParam;
Map<String,Object> extraParams1 = new HashMap<>();
extraParams1.put("json_path", "metadata[\"category\"]");
extraParams1.put("json_cast_type", "varchar");
indexParams.add(IndexParam.builder()
.fieldName("metadata")
.indexName("category_index")
.indexType(IndexParam.IndexType.AUTOINDEX)
.extraParams(extraParams1)
.build());
Map<String,Object> extraParams2 = new HashMap<>();
extraParams2.put("json_path", "metadata[\"tags\"]");
extraParams2.put("json_cast_type", "array_varchar");
indexParams.add(IndexParam.builder()
.fieldName("metadata")
.indexName("tags_array_index")
.indexType(IndexParam.IndexType.AUTOINDEX)
.extraParams(extraParams2)
.build());
const indexParams = [
{
collection_name: "product_catalog",
field_name: "metadata",
index_name: "category_index",
index_type: "AUTOINDEX", // Can also use "INVERTED" for JSON path indexing
extra_params: {
json_path: 'metadata["category"]',
json_cast_type: "varchar",
},
},
{
collection_name: "product_catalog",
field_name: "metadata",
index_name: "tags_array_index",
index_type: "AUTOINDEX", // Can also use "INVERTED" for JSON path indexing
extra_params: {
json_path: 'metadata["tags"]',
json_cast_type: "array_varchar",
},
},
];
import (
"github.com/milvus-io/milvus/client/v2/index"
)
jsonIndex1 := index.NewJSONPathIndex(index.AUTOINDEX, "varchar", `metadata["category"]`)
.WithIndexName("category_index")
jsonIndex2 := index.NewJSONPathIndex(index.AUTOINDEX, "array_varchar", `metadata["tags"]`)
.WithIndexName("tags_array_index")
indexOpt1 := milvusclient.NewCreateIndexOption("product_catalog", "metadata", jsonIndex1)
indexOpt2 := milvusclient.NewCreateIndexOption("product_catalog", "metadata", jsonIndex2)
# restful
export categoryIndex='{
"fieldName": "metadata",
"indexName": "category_index",
"params": {
"index_type": "AUTOINDEX",
"json_path": "metadata[\\\"category\\\"]",
"json_cast_type": "varchar"
}
}'
export tagsArrayIndex='{
"fieldName": "metadata",
"indexName": "tags_array_index",
"params": {
"index_type": "AUTOINDEX",
"json_path": "metadata[\\\"tags\\\"]",
"json_cast_type": "array_varchar"
}
}'
型変換にJSONキャスト関数を使用するCompatible with Milvus 2.5.14+
JSONフィールドキーに不正な形式の値(文字列として格納された数値など)が含まれている場合、インデックス作成時にキャスト関数を使用して値を変換できます。
サポートされるキャスト関数
キャスト関数は大文字と小文字を区別しません。以下の型がサポートされています:
キャスト関数 |
変換元 → 変換先 |
使用例 |
|---|---|---|
|
文字列 → 数値(double) |
|
例文字列の数値を double に変換
# Convert string numbers to double for indexing
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX", # Must be set to AUTOINDEX or INVERTED for JSON path indexing
index_name="string_to_double_index", # Unique index name
params={
"json_path": "metadata[\"string_price\"]", # Path to the JSON key to be indexed
"json_cast_type": "double", # Data cast type
"json_cast_function": "STRING_TO_DOUBLE" # Cast function; case insensitive
}
)
Map<String,Object> extraParams3 = new HashMap<>();
extraParams3.put("json_path", "metadata[\"string_price\"]");
extraParams3.put("json_cast_type", "double");
extraParams3.put("json_cast_function", "STRING_TO_DOUBLE");
indexParams.add(IndexParam.builder()
.fieldName("metadata")
.indexName("string_to_double_index")
.indexType(IndexParam.IndexType.AUTOINDEX)
.extraParams(extraParams3)
.build());
indexParams.push({
collection_name: "product_catalog",
field_name: "metadata",
index_name: "string_to_double_index",
index_type: "AUTOINDEX", // Can also use "INVERTED"
extra_params: {
json_path: 'metadata["string_price"]',
json_cast_type: "double",
json_cast_function: "STRING_TO_DOUBLE", // Case insensitive
},
});
jsonIndex3 := index.NewJSONPathIndex(index.AUTOINDEX, "double", `metadata["string_price"]`)
.WithIndexName("string_to_double_index")
indexOpt3 := milvusclient.NewCreateIndexOption("product_catalog", "metadata", jsonIndex3)
# restful
export stringToDoubleIndex='{
"fieldName": "metadata",
"indexName": "string_to_double_index",
"params": {
"index_type": "AUTOINDEX",
"json_path": "metadata[\\\"string_price\\\"]",
"json_cast_type": "double",
"json_cast_function": "STRING_TO_DOUBLE"
}
}'
json_cast_typeパラメータは必須で、キャスト関数の出力型と同じでなければならない。変換に失敗した場合(例:数値以外の文字列)、その値はスキップされ、インデックス化されません。
JSONフラットインデックスCompatible with Milvus 2.6.x
JSONフラットインデックスでは、MilvusはJSON構造を平坦化し、各値の型を自動的に推論することで、JSONオブジェクトパス内のすべてのキーと値のペア(ネストされたオブジェクトを含む)にインデックスを付けます。
フラット化と型推論の仕組み
オブジェクトパス上にJSONフラットインデックスを作成すると、Milvusは以下の処理を行います:
フラット化- 指定された
json_pathから再帰的にオブジェクトを走査し、入れ子になったキーと値のペアを完全修飾パスとして抽出します。先のmetadataの例を使用すると"metadata": { "category": "electronics", "price": 99.99, "supplier": { "country": "USA" } }になります:
metadata["category"] = "electronics" metadata["price"] = 99.99 metadata["supplier"]["country"] = "USA"型を自動的に推測する- Milvusは各値に対して、以下の順序で型を決定します:
unsigned integer → signed integer → floating-point → string値に適合する最初の型がインデックス作成に使用されます。
つまり、推論される型は常にこの4つのうちの1つになります。
型推論は文書ごとに行われるため、同じパスでも文書によって推論される型が異なることがあります。
型推論の後、平坦化されたデータは、推論された型を持つ用語として内部的に表現されます:
("category", Text, "electronics") ("price", Double, 99.99) ("supplier.country", Text, "USA")
例JSONフラットインデックスの作成
# 1. Create a flat index on the root object of the JSON column (covers the entire JSON subtree)
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX", # Or "INVERTED", same as Path Index
index_name="metadata_flat", # Unique index name
params={
"json_path": 'metadata', # Object path: the root object of the column
"json_cast_type": "JSON" # Key difference: must be "JSON" for Flat Index; case-insensitive
}
)
# 2. Optionally, create a flat index on a sub-object (e.g., supplier subtree)
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="metadata_supplier_flat",
params={
"json_path": 'metadata["supplier"]', # Object path: sub-object path
"json_cast_type": "JSON"
}
)
// java
// nodejs
// go
# restful
コレクションへのインデックスの適用
インデックスパラメータを定義したら、create_index() を使用してコレクションに適用できます:
client.create_index(
collection_name="product_catalog",
index_params=index_params
)
import io.milvus.v2.service.index.request.CreateIndexReq;
client.createIndex(CreateIndexReq.builder()
.collectionName("product_catalog")
.indexParams(indexParams)
.build());
await client.createIndex(indexParams)
indexTask1, err := client.CreateIndex(ctx, indexOpt1)
if err != nil {
return err
}
indexTask2, err := client.CreateIndex(ctx, indexOpt2)
if err != nil {
return err
}
indexTask3, err := client.CreateIndex(ctx, indexOpt3)
if err != nil {
return err
}
# restful
export indexParams="[
$categoryIndex,
$tagsArrayIndex,
$stringToDoubleIndex
]"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data "{
\"collectionName\": \"product_catalog\",
\"indexParams\": $indexParams
}"
JSON フィールド値によるフィルター
JSONフィールドを挿入してインデックスを作成した後、JSONパス構文を使用した標準的なフィルター式を使用して、JSONフィールドにフィルターをかけることができます。
例えば
filter = 'metadata["category"] == "electronics"'
filter = 'metadata["price"] > 50'
filter = 'json_contains(metadata["tags"], "featured")'
String filter = 'metadata["category"] == "electronics"';
String filter = 'metadata["price"] > 50';
String filter = 'json_contains(metadata["tags"], "featured")';
let filter = 'metadata["category"] == "electronics"'
let filter = 'metadata["price"] > 50'
let filter = 'json_contains(metadata["tags"], "featured")'
filter := 'metadata["category"] == "electronics"'
filter := 'metadata["price"] > 50'
filter := 'json_contains(metadata["tags"], "featured")'
# restful
export filterCategory='metadata["category"] == "electronics"'
export filterPrice='metadata["price"] > 50'
export filterTags='json_contains(metadata["tags"], "featured")'
検索やクエリでこれらの式を使用するには、以下を確認してください:
各ベクトル・フィールドにインデックスが作成されている。
コレクションがメモリにロードされている。
サポートされている演算子および式の完全なリストについては、JSON 演算子を参照してください。
すべてをまとめる
ここまでで、JSONフィールド内に構造化値を定義、挿入、およびオプションでインデックスを作成する方法を学びました。
実際のアプリケーションでワークフローを完成させるには、次のことも行う必要があります:
ベクトルフィールドにインデックスを作成する(コレクション内の各ベクトルフィールドに必須)。
インデックス・パラメータの設定」を参照。
コレクションをロードする。
JSONパスフィルタを使用した検索またはクエリ
FAQ
JSONフィールドとダイナミックフィールドの違いは何ですか?
JSONフィールドはスキーマ定義です。スキーマで明示的にフィールドを宣言する必要があります。
ダイナミック・フィールドは、スキーマで定義されていないフィールドを自動的に格納する隠しJSONオブジェクト(
$meta)です。
どちらも入れ子構造やJSONパス・インデックスをサポートしていますが、ダイナミック・フィールドの方がオプションや進化するデータ構造に適しています。
詳細はダイナミック・フィールドを参照してください。
JSONフィールドのサイズに制限はありますか?
あります。各JSONフィールドは65,536バイトに制限されています。
JSONフィールドはデフォルト値の設定をサポートしていますか?
いいえ、JSONフィールドはデフォルト値をサポートしていません。ただし、フィールドの定義時にnullable=True を設定して、空の入力を許可することはできます。
詳細は「Nullable & Default」を参照してください。
JSONフィールド・キーの命名規則はありますか?
はい、クエリとインデックス作成の互換性を確保するためです:
JSONキーには、文字、数字、アンダースコアのみを使用してください。
JSONキーには、文字、数字、アンダースコアのみを使用してください。特殊文字、スペース、ドット(
.、/など)の使用は避けてください。互換性のないキーは、フィルタ式において解析上の問題を引き起こす可能性があります。
MilvusはJSONフィールド内の文字列値をどのように扱いますか?
Milvusは文字列値をJSON入力と同じように保存します。文字列が不適切に引用符で囲まれていると、パース時にエラーが発生する可能性があります。
有効な文字列の例
"a\"b", "a'b", "a\\b"
無効な文字列の例
'a"b', 'a\'b'
Milvusはインデックス付きJSONパスにどのようなフィルタリングロジックを使用しますか?
数値インデックス:
インデックスが
json_cast_type="double"で作成された場合、数値フィルタ条件 (>,<,== 42など) だけがインデックスを利用します。数値以外の条件は、ブルートフォーススキャンにフォールバックする可能性があります。文字列インデックス:
文字列インデクシング: インデックスが
json_cast_type="varchar"を使用している場合、文字列フィルタ条件のみが インデックスの恩恵を受ける。ブールインデックス:
ブールインデクシングは文字列インデクシングと同様の動作をし、条件が厳密に真か偽に一致するときのみインデックスを使用する。
JSONフィールドのインデックスを作成する際の数値精度についてはどうでしょうか?
Milvusはインデックスされたすべての数値をdoubleとして保存します。
数値が2^53を超えると、精度を失う可能性があります。この精度の低下により、フィルタクエリが範囲外の値に正確にマッチしなくなる可能性があります。
同じJSONパスに異なるキャスト・タイプで複数のインデックスを作成できますか?
いいえ、各 JSON パスがサポートするインデックスは 1 つだけです。データに一致する 1 つのjson_cast_type を選択する必要があります。異なるキャスト・タイプで同じパスに複数のインデックスを作成することはサポートされていません。
JSON パス上の値に一貫性のない型がある場合はどうなりますか?
エンティティ間で型が一貫していないと、部分的なインデックスが作成される可能性があります。たとえば、metadata["price"] が数値 (99.99) と文字列 ("99.99") の両方として格納され、インデックスがjson_cast_type="double" で定義されている場合、数値のみがインデックス化されます。文字列形式のエントリはスキップされ、フィルタ結果には表示されません。
インデックス付きキャスト型とは異なる型のフィルタを使用できますか?
フィルター式がインデックスのjson_cast_type と異なる型を使用する場合、システムはインデックスを使用せず、データが許す限り、より遅いブルートフォーススキャンにフォールバックする可能性があります。最高のパフォーマンスを得るためには、フィルタ式を常にインデックスのキャスト型に合わせてください。