Milvus
Zilliz
Home

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:

  • metadata ist 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 metadata Feld vom Typ JSON, 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 json_cast_type (skalare Typen)

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

bool

Boolescher Wert

true, false

double

Numerischer Wert (Integer oder Float)

42, 99.99, -15.5

varchar

String-Wert

"electronics", "BrandA"

array_bool

Array von Booleschen Werten

[true, false, true]

array_double

Array von Zahlen

[1.2, 3.14, 42]

array_varchar

Array mit Zeichenketten

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

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

String → Numerisch (double)

Konvertiert "99.99" in 99.99

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_type ist 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:

  1. Flatten - Rekursives Durchlaufen des Objekts, beginnend mit dem angegebenen json_path und Extrahieren verschachtelter Schlüssel-Wert-Paare als voll qualifizierte Pfade. Unter Verwendung des früheren metadata Beispiels:

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

    wird:

    metadata["category"] = "electronics"
    metadata["price"] = 99.99
    metadata["supplier"]["country"] = "USA"
    
  2. Typen automatisch ableiten - Für jeden Wert bestimmt Milvus seinen Typ in der folgenden Reihenfolge:

    unsigned integer → signed integer → floating-point → string
    

    Der 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

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.