JSON-Feld
Milvus ermöglicht Ihnen die Speicherung und Indizierung strukturierter Daten in einem einzigen Feld unter Verwendung des Datentyps JSON. Dies ermöglicht flexible Schemata mit verschachtelten Attributen und gleichzeitig eine effiziente Filterung über JSON-Indizierung.
Was ist ein JSON-Feld?
Ein JSON-Feld ist ein schema-definiertes Feld in Milvus, das strukturierte Schlüssel-Wert-Daten speichert. Die Werte können Strings, Zahlen, Boolesche Werte, Arrays oder tief verschachtelte Objekte enthalten.
Hier ist ein Beispiel dafür, wie ein JSON-Feld in einem Dokument aussehen könnte:
{
"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"
}
}
}
}
In diesem Beispiel:
metadataist das im Schema definierte JSON-Feld.Sie können flache Werte (z. B.
category,in_stock), Arrays (tags) und verschachtelte Objekte (supplier) speichern.
Definieren Sie ein JSON-Feld im Schema
Um ein JSON-Feld zu verwenden, definieren Sie es explizit im Schema der Sammlung, indem Sie DataType als JSON angeben.
Im folgenden Beispiel wird eine Sammlung erstellt, deren Schema diese Felder enthält:
Den Primärschlüssel (
product_id)Ein Feld
vector(obligatorisch für jede Sammlung)Ein
metadataFeld vom TypJSON, das strukturierte Daten wie flache Werte, Arrays oder verschachtelte Objekte speichern kann
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
}"
Sie können auch die Funktion "Dynamisches Feld" aktivieren, um nicht deklarierte Felder flexibel zu speichern, aber das ist für die Funktion von JSON-Feldern nicht erforderlich. Weitere Informationen finden Sie unter Dynamisches Feld.
Einfügen von Entitäten mit JSON-Daten
Sobald die Sammlung erstellt ist, fügen Sie Entitäten, die strukturierte JSON-Objekte enthalten, in das metadata JSON-Feld ein.
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
}"
Indexwerte innerhalb des JSON-Feldes
Um die skalare Filterung auf JSON-Feldern zu beschleunigen, unterstützt Milvus die folgenden Arten von Indizes:
JSON-Pfadindex - indexiert bestimmte JSON-Pfade mit einem deklarierten skalaren Typ.
JSON flat index - indiziert ein ganzes JSON-Objekt (oder einen Teilbaum) mit automatischer Typisierung.
Die Indizierung von JSON-Feldern ist optional. Sie können auch ohne Index nach JSON-Pfaden abfragen oder filtern, aber dies kann zu einer langsameren Leistung aufgrund der Brute-Force-Suche führen.
Wählen Sie zwischen Pfadindex und flachem IndexCompatible with Milvus 2.6.x
Fähigkeit |
JSON-Pfad-Index |
Flacher JSON-Index |
|---|---|---|
Was er indiziert |
Spezifische(r) Pfad(e), die Sie benennen |
Alle abgeflachten Pfade unter einem Objektpfad |
Behandlung von Typen |
Sie deklarieren |
Muss JSON sein (automatische Typinferenz) |
Arrays als LHS¹ |
Unterstützt |
Nicht unterstützt |
Abfragegeschwindigkeit |
Hoch bei indizierten Pfaden |
Hoch, im Durchschnitt etwas niedriger |
Festplattennutzung |
Niedriger |
Höher |
¹ Arrays als LHS bedeutet, dass die linke Seite des Filterausdrucks z. B. ein JSON-Array ist:
metadata["tags"] == ["clearance", "summer_sale"]
json_contains(metadata["tags"], "clearance")
In diesen Fällen ist metadata["tags"] ein Array. JSON flat indexing beschleunigt solche Filter nicht - verwenden Sie stattdessen einen JSON path index mit einem Array cast type.
Verwenden Sie den JSON-Pfadindex, wenn:
Sie die abzufragenden Hotkeys im Voraus kennen.
Sie filtern müssen, wenn die linke Seite ein Array ist.
Sie die Plattennutzung minimieren möchten.
Verwenden Sie einen flachen JSON-Index, wenn:
Sie einen ganzen Teilbaum (einschließlich der Wurzel) indizieren möchten.
Ihre JSON-Struktur sich häufig ändert.
Sie eine breitere Abfrageabdeckung wünschen, ohne jeden Pfad zu deklarieren.
JSON-Pfad-Indizierung
Um einen JSON-Pfadindex zu erstellen, geben Sie an:
JSON path (
json_path): Der Pfad zu dem Schlüssel oder dem verschachtelten Feld in Ihrem JSON-Objekt, das Sie indizieren möchten.Beispiel:
Für einen Schlüssel,
metadata["category"]Für ein verschachteltes Feld,
metadata["contact"]["email"]
Damit wird festgelegt, wo die Indizierungsmaschine innerhalb der JSON-Struktur suchen soll.
JSON-Cast-Typ (
json_cast_type): Der Datentyp, den Milvus bei der Interpretation und Indizierung des Wertes am angegebenen Pfad verwenden soll.Dieser Typ muss mit dem tatsächlichen Datentyp des zu indizierenden Feldes übereinstimmen. Wenn Sie den Datentyp während der Indizierung in einen anderen konvertieren wollen, sollten Sie eine Cast-Funktion verwenden.
Eine vollständige Liste finden Sie unten.
Unterstützte JSON-Cast-Typen
Bei Cast-Typen wird die Groß- und Kleinschreibung nicht berücksichtigt. Die folgenden Typen werden unterstützt:
Cast-Typ |
Beschreibung |
Beispiel JSON-Wert |
|---|---|---|
|
Boolescher Wert |
|
|
Numerischer Wert (Integer oder Float) |
|
|
String-Wert |
|
|
Array von Booleschen Werten |
|
|
Array von Zahlen |
|
|
Array mit Zeichenketten |
|
Arrays sollten für eine optimale Indizierung Elemente desselben Typs enthalten. Weitere Informationen finden Sie unter Array-Feld.
Beispiel: JSON-Pfadindizes erstellen
Unter Verwendung der metadata JSON-Struktur aus unserer Einführung, sind hier Beispiele, wie man Indizes auf verschiedenen JSON-Pfaden erstellen kann:
# 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"
}
}'
Verwenden Sie JSON-Cast-Funktionen für die TypkonvertierungCompatible with Milvus 2.5.14+
Wenn Ihr JSON-Feldschlüssel Werte in einem falschen Format enthält (z. B. Zahlen, die als Strings gespeichert sind), können Sie Cast-Funktionen verwenden, um Werte während der Indizierung zu konvertieren.
Unterstützte Cast-Funktionen
Bei Cast-Funktionen wird die Groß-/Kleinschreibung nicht berücksichtigt. Die folgenden Typen werden unterstützt:
Cast-Funktion |
Konvertiert von → nach |
Anwendungsfall |
|---|---|---|
|
String → Numerisch (double) |
Konvertiert |
Beispiel: String-Zahlen in double umwandeln
# 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"
}
}'
Der Parameter
json_cast_typeist obligatorisch und muss mit dem Ausgabetyp der Cast-Funktion übereinstimmen.Wenn die Konvertierung fehlschlägt (z.B. nicht-numerischer String), wird der Wert übersprungen und nicht indiziert.
Flache JSON-IndizierungCompatible with Milvus 2.6.x
Bei der flachen JSON-Indizierung indiziert Milvus alle Schlüssel-Wert-Paare innerhalb eines JSON-Objektpfades (einschließlich verschachtelter Objekte), indem es die JSON-Struktur reduziert und automatisch den Typ jedes Wertes ableitet.
Wie Flattening und Typinferenz funktionieren
Wenn Sie einen flachen JSON-Index für einen Objektpfad erstellen, wird Milvus:
Flatten - Rekursives Durchlaufen des Objekts, beginnend mit dem angegebenen
json_pathund Extrahieren verschachtelter Schlüssel-Wert-Paare als voll qualifizierte Pfade. Unter Verwendung des früherenmetadataBeispiels:"metadata": { "category": "electronics", "price": 99.99, "supplier": { "country": "USA" } }wird:
metadata["category"] = "electronics" metadata["price"] = 99.99 metadata["supplier"]["country"] = "USA"Typen automatisch ableiten - Für jeden Wert bestimmt Milvus seinen Typ in der folgenden Reihenfolge:
unsigned integer → signed integer → floating-point → stringDer erste Typ, der auf den Wert passt, wird für die Indizierung verwendet.
Das bedeutet, dass der ermittelte Typ immer einer dieser vier ist.
Die Typisierung wird für jedes Dokument durchgeführt, so dass ein und derselbe Pfad in verschiedenen Dokumenten unterschiedliche abgeleitete Typen haben kann.
Nach der Typisierung werden die reduzierten Daten intern als Terme mit ihren abgeleiteten Typen dargestellt, zum Beispiel:
("category", Text, "electronics") ("price", Double, 99.99) ("supplier.country", Text, "USA")
Beispiel: Erstellen eines flachen JSON-Index
# 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
Indizes auf die Sammlung anwenden
Nachdem Sie die Indexparameter definiert haben, können Sie sie mit create_index() auf die Sammlung anwenden:
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
}"
Nach JSON-Feldwerten filtern
Nach dem Einfügen und Indizieren von JSON-Feldern können Sie mit Standard-Filterausdrücken mit JSON-Pfadsyntax nach ihnen filtern.
Zum Beispiel:
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")'
Um diese Ausdrücke in einer Suche oder Abfrage zu verwenden, stellen Sie sicher, dass:
Sie haben einen Index für jedes Vektorfeld erstellt.
Die Sammlung ist in den Speicher geladen.
Eine vollständige Liste der unterstützten Operatoren und Ausdrücke finden Sie unter JSON-Operatoren.
Alles zusammenfassen
Inzwischen haben Sie gelernt, wie man strukturierte Werte innerhalb eines JSON-Feldes definiert, einfügt und optional indiziert.
Um den Arbeitsablauf in einer realen Anwendung zu vervollständigen, müssen Sie auch Folgendes tun
Erstellen Sie einen Index für Ihre Vektorfelder (obligatorisch für jedes Vektorfeld in einer Sammlung)
Siehe Indexparameter festlegen
Laden Sie die Sammlung
Siehe Laden & Freigeben
Suchen oder Abfragen mit JSON-Pfadfiltern
Siehe Gefilterte Suche und JSON-Operatoren
FAQ
Was sind die Unterschiede zwischen einem JSON-Feld und einem dynamischen Feld?
DasJSON-Feld ist schema-definiert. Sie müssen das Feld explizit im Schema deklarieren.
Dasdynamische Feld ist ein verstecktes JSON-Objekt (
$meta), das automatisch jedes Feld speichert, das nicht im Schema definiert ist.
Beide unterstützen verschachtelte Strukturen und JSON-Pfadindizierung, aber dynamische Felder sind besser für optionale oder sich entwickelnde Datenstrukturen geeignet.
Weitere Informationen finden Sie unter Dynamisches Feld.
Gibt es irgendwelche Beschränkungen für die Größe eines JSON-Feldes?
Ja. Jedes JSON-Feld ist auf 65.536 Byte begrenzt.
Unterstützt ein JSON-Feld die Festlegung eines Standardwerts?
Nein, JSON-Felder unterstützen keine Standardwerte. Sie können jedoch nullable=True festlegen, wenn Sie das Feld definieren, um leere Einträge zuzulassen.
Weitere Informationen finden Sie unter Nullable & Default.
Gibt es Namenskonventionen für JSON-Feldschlüssel?
Ja, um die Kompatibilität mit Abfragen und Indizierungen zu gewährleisten:
Verwenden Sie in JSON-Schlüsseln nur Buchstaben, Zahlen und Unterstriche.
Vermeiden Sie die Verwendung von Sonderzeichen, Leerzeichen oder Punkten (
.,/, etc.).Inkompatible Schlüssel können zu Parsing-Problemen in Filterausdrücken führen.
Wie behandelt Milvus Zeichenkettenwerte in JSON-Feldern?
Milvus speichert String-Werte genau so, wie sie in der JSON-Eingabe erscheinen - ohne semantische Umwandlung. Nicht korrekt zitierte Zeichenketten können beim Parsen zu Fehlern führen.
Beispiele für gültige Zeichenketten:
"a\"b", "a'b", "a\\b"
Beispiele für ungültige Zeichenketten:
'a"b', 'a\'b'
Welche Filterlogik verwendet Milvus für indizierte JSON-Pfade?
Numerische Indizierung:
Wenn ein Index mit
json_cast_type="double"erstellt wird, werden nur numerische Filterbedingungen (z. B.>,<,== 42) den Index nutzen. Nicht numerische Bedingungen können auf einen Brute-Force-Scan zurückgreifen.String-Indizierung:
Wenn ein Index
json_cast_type="varchar"verwendet, profitieren nur String-Filterbedingungen von dem Index; andere Typen können auf einen Brute-Force-Scan zurückfallen.Boolesche Indizierung:
Die boolesche Indizierung verhält sich ähnlich wie die Zeichenkettenindizierung, wobei der Index nur dann verwendet wird, wenn die Bedingung strikt wahr oder falsch ist.
Was ist mit der numerischen Präzision bei der Indizierung von JSON-Feldern?
Milvus speichert alle indizierten numerischen Werte als Doubles.
Wenn ein numerischer Wert 2^53 überschreitet, kann er an Präzision verlieren. Dieser Präzisionsverlust kann dazu führen, dass Filterabfragen nicht genau mit Werten übereinstimmen, die außerhalb des Bereichs liegen.
Kann ich mehrere Indizes für denselben JSON-Pfad mit unterschiedlichen Cast-Typen erstellen?
Nein, jeder JSON-Pfad unterstützt nur einen Index. Sie müssen einen einzigen json_cast_type wählen, der Ihren Daten entspricht. Das Erstellen mehrerer Indizes auf demselben Pfad mit unterschiedlichen Cast-Typen wird nicht unterstützt.
Was passiert, wenn Werte in einem JSON-Pfad inkonsistente Typen haben?
Inkonsistente Typen zwischen Entitäten können zu einer teilweisen Indizierung führen. Wenn beispielsweise metadata["price"] sowohl als Zahl (99.99) als auch als Zeichenkette ("99.99") gespeichert ist und der Index mit json_cast_type="double" definiert wird, werden nur die numerischen Werte indiziert. Die Einträge in String-Form werden übersprungen und erscheinen nicht in den Filterergebnissen.
Kann ich Filter mit einem anderen Typ als dem indizierten Cast-Typ verwenden?
Wenn Ihr Filterausdruck einen anderen Typ als den des Index json_cast_type verwendet, verwendet das System den Index nicht und kann auf einen langsameren Brute-Force-Scan zurückgreifen, sofern die Daten dies zulassen. Um die beste Leistung zu erzielen, sollten Sie Ihren Filterausdruck immer an den Cast-Typ des Indexes anpassen.