• Tentang Milvus
  • Memulai
  • Konsep
  • Panduan Pengguna
  • Impor Data
  • Alat AI
  • Panduan Administrasi
  • Peralatan
  • Integrasi
  • Tutorial
  • Pertanyaan Umum
  • API Reference

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:

  • metadata adalah 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 metadata dengan tipe JSON, 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 json_cast_type (tipe skalar)

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

bool

Nilai Boolean

true, false

double

Nilai numerik (bilangan bulat atau float)

42, 99.99, -15.5

varchar

Nilai string

"electronics", "BrandA"

array_bool

Larik boolean

[true, false, true]

array_double

Larik angka

[1.2, 3.14, 42]

array_varchar

Larik string

["tag1", "tag2", "tag3"]

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_TO_DOUBLE"

String → Numerik (ganda)

Ubah "99.99" menjadi 99.99

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_type adalah 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

  1. Meratakan - Secara rekursif menelusuri objek mulai dari json_path yang ditentukan dan mengekstrak pasangan nilai-kunci bersarang sebagai jalur yang memenuhi syarat. Menggunakan contoh metadata sebelumnya:

    "metadata": {
      "category": "electronics",
      "price": 99.99,
      "supplier": { "country": "USA" }
    }
    

    menjadi:

    metadata["category"] = "electronics"
    metadata["price"] = 99.99
    metadata["supplier"]["country"] = "USA"
    
  2. Menyimpulkan tipe secara otomatis - Untuk setiap nilai, Milvus menentukan tipenya dengan urutan sebagai berikut:

    unsigned integer → signed integer → floating-point → string
    

    Tipe 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:

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.