Bidang JSON
Milvus memungkinkan Anda untuk menyimpan dan mengindeks data terstruktur dalam satu bidang menggunakan tipe data JSON. Hal ini memungkinkan skema yang fleksibel dengan atribut bersarang sambil tetap memungkinkan pemfilteran yang efisien melalui pengindeksan JSON.
Apa yang dimaksud dengan bidang JSON?
Bidang JSON adalah bidang yang ditentukan oleh skema di Milvus yang menyimpan data nilai-kunci terstruktur. Nilai-nilai tersebut dapat berupa string, angka, boolean, array, atau objek bersarang.
Berikut ini contoh tampilan field JSON dalam sebuah dokumen:
{
"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"
}
}
}
}
Dalam contoh ini:
metadataadalah bidang JSON yang didefinisikan dalam skema.Anda dapat menyimpan nilai datar (misalnya
category,in_stock), larik (tags), dan objek bersarang (supplier).
Mendefinisikan bidang JSON di dalam skema
Untuk menggunakan bidang JSON, tentukan secara eksplisit di dalam skema koleksi dengan menentukan DataType sebagai JSON.
Contoh di bawah ini membuat koleksi dengan skema yang berisi bidang-bidang ini:
Kunci utama (
product_id)Bidang
vector(wajib untuk setiap koleksi)Bidang
metadatadengan tipeJSON, yang dapat menyimpan data terstruktur seperti nilai datar, array, atau objek bersarang
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" \
--header "Request-Timeout: 10" \
--data "{
\"collectionName\": \"product_catalog\",
\"schema\": $schema
}"
Anda juga dapat mengaktifkan fitur bidang dinamis untuk menyimpan bidang yang tidak dideklarasikan secara fleksibel, tetapi fitur ini tidak diperlukan agar bidang JSON dapat berfungsi. Untuk informasi lebih lanjut, lihat Bidang Dinamis.
Menyisipkan entitas dengan data JSON
Setelah koleksi dibuat, sisipkan entitas yang berisi objek JSON terstruktur di bidang JSON metadata.
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" \
--header "Request-Timeout: 10" \
--data "{
\"data\": $entities
}"
Mengindeks nilai di dalam bidang JSON
Untuk mempercepat pemfilteran skalar pada bidang JSON, Milvus mendukung jenis-jenis indeks berikut ini:
Indeks jalur JSON - mengindeks jalur JSON tertentu dengan tipe skalar yang dideklarasikan.
Indeks datar JSON - mengindeks seluruh objek JSON (atau subtree) dengan inferensi tipe otomatis.
Mengindeks bidang JSON bersifat opsional. Anda masih bisa melakukan kueri atau memfilter berdasarkan jalur JSON tanpa indeks, namun hal ini bisa mengakibatkan kinerja yang lebih lambat karena pencarian secara brute force.
Pilih antara indeks jalur dan indeks datarCompatible with Milvus 2.6.x
Kemampuan |
Indeks Jalur JSON |
Indeks Datar JSON |
|---|---|---|
Apa yang diindeks |
Jalur spesifik yang Anda beri nama |
Semua jalur yang diratakan di bawah jalur objek |
Penanganan tipe |
Anda mendeklarasikan |
Harus berupa JSON (inferensi tipe otomatis) |
Larik sebagai LHS¹ |
Didukung |
Tidak didukung |
Kecepatan kueri |
Tinggi pada jalur yang diindeks |
Tinggi, rata-rata sedikit lebih rendah |
Penggunaan disk |
Lebih rendah |
Lebih tinggi |
¹ Larik sebagai LHS berarti sisi kiri ekspresi filter adalah larik JSON, misalnya:
metadata["tags"] == ["clearance", "summer_sale"]
json_contains(metadata["tags"], "clearance")
Dalam kasus ini, metadata["tags"] adalah sebuah larik. Pengindeksan datar JSON tidak mempercepat filter semacam itu - gunakan indeks jalur JSON dengan tipe cast array sebagai gantinya.
Gunakan indeks jalur JSON ketika:
Anda sudah mengetahui tombol pintas untuk melakukan kueri sebelumnya.
Anda perlu memfilter di mana sisi kiri adalah larik.
Anda ingin meminimalkan penggunaan disk.
Gunakan indeks datar JSON bila:
Anda ingin mengindeks seluruh subpohon (termasuk akar).
Struktur JSON Anda sering berubah.
Anda menginginkan cakupan kueri yang lebih luas tanpa mendeklarasikan setiap jalur.
Pengindeksan jalur JSON
Untuk membuat indeks jalur JSON, tentukan:
Jalur JSON (
json_path): Jalur ke kunci atau bidang bersarang di dalam objek JSON yang ingin Anda indeks.Contoh:
Untuk sebuah kunci,
metadata["category"]Untuk bidang bersarang,
metadata["contact"]["email"]
Ini menentukan di mana mesin pengindeks harus mencari di dalam struktur JSON.
Tipe cast JSON (
json_cast_type): Tipe data yang harus digunakan Milvus ketika menginterpretasikan dan mengindeks nilai pada jalur yang ditentukan.Tipe ini harus sesuai dengan tipe data aktual dari bidang yang diindeks. Jika Anda ingin mengubah tipe data menjadi tipe data lain selama pengindeksan, pertimbangkan untuk menggunakan fungsi cast.
Untuk daftar lengkapnya, lihat di bawah ini.
Jenis cast JSON yang didukung
Tipe cast tidak peka terhadap huruf besar/kecil. Jenis-jenis berikut ini didukung:
Tipe Cast |
Deskripsi |
Contoh Nilai JSON |
|---|---|---|
|
Nilai Boolean |
|
|
Nilai numerik (bilangan bulat atau float) |
|
|
Nilai string |
|
|
Larik boolean |
|
|
Larik angka |
|
|
Larik string |
|
Larik harus berisi elemen dengan tipe yang sama untuk pengindeksan optimal. Untuk informasi lebih lanjut, lihat Bidang Larik.
Contoh: Membuat indeks jalur JSON
Dengan menggunakan struktur JSON metadata dari pengenalan kita, berikut ini adalah contoh cara membuat indeks pada jalur JSON yang berbeda:
# 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"
}
}'
Gunakan fungsi cast JSON untuk konversi tipeCompatible with Milvus 2.5.14+
Jika kunci bidang JSON Anda berisi nilai dalam format yang salah (misalnya, angka yang disimpan sebagai string), Anda dapat menggunakan fungsi cast untuk mengonversi nilai selama pengindeksan.
Fungsi cast yang didukung
Fungsi cast tidak peka terhadap huruf besar/kecil. Jenis berikut ini didukung:
Fungsi Cast |
Mengonversi Dari → Ke |
Kasus Penggunaan |
|---|---|---|
|
String → Numerik (ganda) |
Ubah |
Contoh: Mengubah angka string menjadi ganda
# 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"
}
}'
Parameter
json_cast_typeadalah wajib dan harus sama dengan tipe keluaran fungsi cast.Jika konversi gagal (misalnya, string non-numerik), nilainya akan dilewati dan tidak diindeks.
Pengindeksan datar JSONCompatible with Milvus 2.6.x
Untuk pengindeksan datar JSON, Milvus mengindeks semua pasangan nilai-kunci dalam jalur objek JSON (termasuk objek bersarang) dengan meratakan struktur JSON dan secara otomatis menyimpulkan jenis setiap nilai.
Bagaimana perataan dan inferensi tipe bekerja
Ketika Anda membuat indeks datar JSON pada jalur objek, Milvus akan
Meratakan - Secara rekursif menelusuri objek mulai dari
json_pathyang ditentukan dan mengekstrak pasangan nilai-kunci bersarang sebagai jalur yang memenuhi syarat. Menggunakan contohmetadatasebelumnya:"metadata": { "category": "electronics", "price": 99.99, "supplier": { "country": "USA" } }menjadi:
metadata["category"] = "electronics" metadata["price"] = 99.99 metadata["supplier"]["country"] = "USA"Menyimpulkan tipe secara otomatis - Untuk setiap nilai, Milvus menentukan tipenya dengan urutan sebagai berikut:
unsigned integer → signed integer → floating-point → stringTipe pertama yang sesuai dengan nilai tersebut digunakan untuk pengindeksan.
Ini berarti tipe yang disimpulkan akan selalu menjadi salah satu dari keempat tipe tersebut.
Inferensi tipe dilakukan per dokumen, sehingga jalur yang sama dapat memiliki tipe yang berbeda di seluruh dokumen.
Setelah inferensi tipe, data yang diratakan direpresentasikan secara internal sebagai istilah dengan tipe yang disimpulkan, misalnya:
("category", Text, "electronics") ("price", Double, 99.99) ("supplier.country", Text, "USA")
Contoh: Membuat indeks datar 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
Menerapkan indeks ke koleksi
Setelah mendefinisikan parameter indeks, Anda dapat menerapkannya ke koleksi menggunakan 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" \
--header "Request-Timeout: 10" \
--data "{
\"collectionName\": \"product_catalog\",
\"indexParams\": $indexParams
}"
Memfilter berdasarkan nilai bidang JSON
Setelah menyisipkan dan mengindeks bidang JSON, Anda dapat memfilternya menggunakan ekspresi filter standar dengan sintaksis jalur JSON.
Sebagai contoh:
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")'
Untuk menggunakan ekspresi ini dalam pencarian atau kueri, pastikan:
Anda telah membuat indeks pada setiap bidang vektor.
Koleksi dimuat ke dalam memori.
Untuk daftar lengkap operator dan ekspresi yang didukung, lihat Operator JSON.
Menggabungkan semuanya
Sekarang, Anda telah mempelajari cara mendefinisikan, menyisipkan, dan mengindeks nilai terstruktur secara opsional di dalam bidang JSON.
Untuk menyelesaikan alur kerja dalam aplikasi dunia nyata, Anda juga perlu:
Membuat indeks pada bidang vektor Anda (wajib untuk setiap bidang vektor dalam koleksi)
Lihat Mengatur Parameter Indeks
Memuat koleksi
Lihat Memuat & Melepaskan
Mencari atau membuat kueri menggunakan filter jalur JSON
Lihat Pencarian yang Difilter dan Operator JSON
PERTANYAAN UMUM
Apa perbedaan antara bidang JSON dan bidang dinamis?
Bidang JSON ditentukan oleh skema. Anda harus mendeklarasikan bidang secara eksplisit di dalam skema.
Field dinamis adalah objek JSON tersembunyi (
$meta) yang secara otomatis menyimpan field apa pun yang tidak didefinisikan dalam skema.
Keduanya mendukung struktur bersarang dan pengindeksan jalur JSON, tetapi bidang dinamis lebih cocok untuk struktur data opsional atau yang terus berkembang.
Lihat Bidang Dinamis untuk detailnya.
Apakah ada batasan ukuran bidang JSON?
Ya. Setiap bidang JSON dibatasi hingga 65.536 byte.
Apakah field JSON mendukung pengaturan nilai default?
Tidak, bidang JSON tidak mendukung nilai default. Namun, Anda dapat mengatur nullable=True saat mendefinisikan bidang untuk mengizinkan entri kosong.
Lihat Nullable & Default untuk detailnya.
Apakah ada konvensi penamaan untuk kunci bidang JSON?
Ya, untuk memastikan kompatibilitas dengan kueri dan pengindeksan:
Gunakan hanya huruf, angka, dan garis bawah pada kunci JSON.
Hindari penggunaan karakter khusus, spasi, atau titik (
.,/, dll.).Kunci yang tidak kompatibel dapat menyebabkan masalah penguraian dalam ekspresi filter.
Bagaimana Milvus menangani nilai string dalam bidang JSON?
Milvus menyimpan nilai string persis seperti yang muncul di input JSON-tanpa transformasi semantik. String yang dikutip dengan tidak benar dapat mengakibatkan kesalahan selama penguraian.
Contoh string yang valid:
"a\"b", "a'b", "a\\b"
Contoh string yang tidak valid:
'a"b', 'a\'b'
Logika pemfilteran apa yang digunakan Milvus untuk jalur JSON yang diindeks?
Pengindeksan Numerik:
Jika indeks dibuat dengan
json_cast_type="double", hanya kondisi filter numerik (misalnya,>,<,== 42) yang akan memanfaatkan indeks. Kondisi non-numerik mungkin akan kembali ke pemindaian brute-force.Pengindeksan String:
Jika indeks menggunakan
json_cast_type="varchar", hanya kondisi filter string yang akan memanfaatkan indeks; jenis lainnya mungkin akan kembali ke pemindaian brute-force.Pengindeksan Boolean:
Pengindeksan Boolean berperilaku mirip dengan pengindeksan string, dengan penggunaan indeks hanya jika kondisinya benar-benar cocok dengan benar atau salah.
Bagaimana dengan ketepatan numerik ketika mengindeks bidang JSON?
Milvus menyimpan semua nilai numerik yang diindeks sebagai nilai ganda.
Jika nilai numerik melebihi 2^53, maka nilai tersebut akan kehilangan presisi. Hilangnya presisi ini dapat mengakibatkan kueri filter tidak dapat mencocokkan nilai di luar rentang dengan tepat.
Dapatkah saya membuat beberapa indeks pada jalur JSON yang sama dengan jenis cast yang berbeda?
Tidak, setiap jalur JSON hanya mendukung satu indeks. Anda harus memilih satu json_cast_type yang cocok dengan data Anda. Membuat beberapa indeks pada jalur yang sama dengan tipe cast yang berbeda tidak didukung.
Bagaimana jika nilai pada jalur JSON memiliki tipe yang tidak konsisten?
Tipe yang tidak konsisten di seluruh entitas dapat menyebabkan pengindeksan parsial. Misalnya, jika metadata["price"] disimpan sebagai angka (99.99) dan string ("99.99"), dan indeks didefinisikan dengan json_cast_type="double", hanya nilai numerik yang akan diindeks. Entri berbentuk string akan dilewati dan tidak akan muncul dalam hasil filter.
Dapatkah saya menggunakan filter dengan tipe yang berbeda dari tipe cast yang diindeks?
Jika ekspresi filter Anda menggunakan jenis yang berbeda dari indeks json_cast_type, sistem tidak akan menggunakan indeks, dan mungkin akan kembali ke pemindaian brute-force yang lebih lambat-jika data memungkinkan. Untuk performa terbaik, selalu selaraskan ekspresi filter Anda dengan tipe cast indeks.