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 데이터로 엔티티 삽입
컬렉션이 생성되면 구조화된 JSON 개체를 포함하는 엔티티를 metadata 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 필드 키에 잘못된 형식의 값(예: 문자열로 저장된 숫자)이 포함된 경우, 색인하는 동안 형 변환 함수를 사용하여 값을 변환할 수 있습니다.
지원되는 형 변환 함수
형 변환 함수는 대소문자를 구분하지 않습니다. 다음 유형이 지원됩니다:
형 변환 함수 |
다음에서 → 다음으로 변환 |
사용 사례 |
|---|---|---|
|
문자열 → 숫자(더블) |
|
예제: 문자열 숫자를 더블로 형변환하기
# 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값에 맞는 첫 번째 유형이 인덱싱에 사용됩니다.
즉, 추론된 유형은 항상 이 네 가지 중 하나가 됩니다.
유형 추론은 문서별로 수행되므로 동일한 경로가 문서마다 다른 유형으로 추론될 수 있습니다.
유형 추론 후, 평활화된 데이터는 내부적으로 예를 들어 추론된 유형을 가진 용어로 표현됩니다:
("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 경로 구문이 포함된 표준 필터 표현식을 사용하여 필터링할 수 있습니다.
예를 들면 다음과 같습니다:
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 을 설정하여 빈 항목을 허용할 수 있습니다.
자세한 내용은 Null 가능 및 기본값을 참조하세요.
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는 인덱싱된 모든 숫자 값을 복수로 저장합니다.
숫자 값이 2^53을 초과하면 정밀도가 손실될 수 있습니다. 이러한 정밀도 손실로 인해 필터 쿼리가 범위를 벗어난 값과 정확히 일치하지 않을 수 있습니다.
동일한 JSON 경로에 서로 다른 형변환 유형을 사용하여 여러 인덱스를 만들 수 있나요?
아니요, 각 JSON 경로는 하나의 인덱스만 지원합니다. 데이터와 일치하는 단일 json_cast_type 을 선택해야 합니다. 동일한 경로에 서로 다른 형 변환 유형을 사용하여 여러 인덱스를 생성하는 것은 지원되지 않습니다.
JSON 경로의 값에 일관되지 않은 유형이 있으면 어떻게 하나요?
엔티티 간에 일관되지 않은 유형은 부분 인덱싱으로 이어질 수 있습니다. 예를 들어 metadata["price"] 가 숫자(99.99)와 문자열("99.99")로 저장되어 있고 색인이 json_cast_type="double" 로 정의되어 있는 경우 숫자 값만 색인됩니다. 문자열 형식의 항목은 건너뛰고 필터 결과에 표시되지 않습니다.
인덱싱된 캐스트 유형과 다른 유형의 필터를 사용할 수 있나요?
필터 표현식이 인덱스의 json_cast_type 과 다른 유형을 사용하는 경우 시스템은 인덱스를 사용하지 않으며, 데이터가 허용하는 경우 느린 무차별 대입 검색으로 돌아갈 수 있습니다. 최상의 성능을 얻으려면 항상 필터 표현식을 인덱스의 형 변환 유형에 맞춰 정렬하세요.