Schema spiegato

Uno schema definisce la struttura dei dati di una collezione. Prima di creare una collezione, è necessario progettare il suo schema. Questa pagina aiuta a comprendere lo schema delle raccolte e a progettare un esempio di schema per conto proprio.

Panoramica

In Milvus, lo schema di una collezione è una tabella di un database relazionale che definisce come Milvus organizza i dati nella collezione.

Uno schema ben progettato è essenziale perché astrae il modello dei dati e decide se è possibile raggiungere gli obiettivi aziendali attraverso una ricerca. Inoltre, poiché ogni riga di dati inserita nella raccolta deve seguire lo schema, contribuisce a mantenere la coerenza dei dati e la qualità a lungo termine. Da un punto di vista tecnico, uno schema ben definito porta a una memorizzazione ben organizzata dei dati delle colonne e a una struttura dell'indice più pulita, aumentando le prestazioni della ricerca.

Uno schema di raccolta ha una chiave primaria, almeno un campo vettoriale e diversi campi scalari. Il diagramma seguente illustra come mappare un articolo in un elenco di campi dello schema.

Schema Design Anatomy Anatomia della progettazione dello schema

La progettazione del modello di dati di un sistema di ricerca comporta l'analisi delle esigenze aziendali e l'astrazione delle informazioni in un modello di dati espresso in forma di schema. Ad esempio, la ricerca di un testo deve essere "indicizzata" convertendo la stringa letterale in un vettore attraverso l'"embedding" e consentendo la ricerca vettoriale. Oltre a questo requisito essenziale, può essere necessario memorizzare altre proprietà, come la data di pubblicazione e l'autore. Questi metadati consentono di affinare le ricerche semantiche attraverso un filtro, restituendo solo i testi pubblicati dopo una data specifica o da un particolare autore. È anche possibile recuperare questi scalari con il testo principale per rendere il risultato della ricerca nell'applicazione. A ciascuno di essi deve essere assegnato un identificatore unico per organizzare questi pezzi di testo, espresso come un numero intero o una stringa. Questi elementi sono essenziali per ottenere una logica di ricerca sofisticata.

Fare riferimento a Schema Design Hands-On per capire come creare uno schema ben progettato.

Creare uno schema

Il seguente frammento di codice mostra come creare uno schema.

from pymilvus import MilvusClient, DataType

schema = MilvusClient.create_schema()
import io.milvus.v2.service.collection.request.CreateCollectionReq;

CreateCollectionReq.CollectionSchema schema = client.createSchema();
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

const schema = []
import "github.com/milvus-io/milvus/client/v2/entity"

schema := entity.NewSchema()
export schema='{
    "fields": []
}'

Aggiungere un campo primario

Il campo primario di una collezione identifica in modo univoco un'entità. Accetta solo valori Int64 o VarChar. I seguenti frammenti di codice mostrano come aggiungere il campo primario.

schema.add_field(
    field_name="my_id",
    datatype=DataType.INT64,
    is_primary=True,
    auto_id=False,
)
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq; 

schema.addField(AddFieldReq.builder()
        .fieldName("my_id")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .autoID(false)
        .build());
schema.push({
    name: "my_id",
    data_type: DataType.Int64,
    is_primary_key: true,
    autoID: false
});
schema.WithField(entity.NewField().WithName("my_id").
    WithDataType(entity.FieldTypeInt64).
    WithIsPrimaryKey(true).
    WithIsAutoID(false),
)
export primaryField='{
    "fieldName": "my_id",
    "dataType": "Int64",
    "isPrimary": true
}'

export schema='{
    \"autoID\": false,
    \"fields\": [
        $primaryField
    ]
}'

Quando si aggiunge un campo, si può chiarire esplicitamente che si tratta di un campo primario, impostando la proprietà is_primary a True. Un campo primario accetta valori Int64 per impostazione predefinita. In questo caso, il valore del campo primario dovrebbe essere un numero intero, simile a 12345. Se si sceglie di usare valori VarChar nel campo primario, il valore dovrebbe essere una stringa, simile a my_entity_1234.

È anche possibile impostare la proprietà autoId su True per fare in modo che Milvus assegni automaticamente i valori del campo primario all'inserimento dei dati.

Si consiglia di affidarsi a autoId in tutti i casi, a meno che non sia utile impostare manualmente le chiavi primarie.

Per maggiori dettagli, consultare Campo primario e AutoId.

Aggiungere campi vettoriali

I campi vettoriali accettano varie incorporazioni vettoriali rade e dense. Su Milvus, è possibile aggiungere quattro campi vettoriali a una collezione. I seguenti frammenti di codice mostrano come aggiungere un campo vettoriale.

schema.add_field(
    field_name="my_vector",
    datatype=DataType.FLOAT_VECTOR,
    dim=5
)
schema.addField(AddFieldReq.builder()
        .fieldName("my_vector")
        .dataType(DataType.FloatVector)
        .dimension(5)
        .build());
schema.push({
    name: "my_vector",
    data_type: DataType.FloatVector,
    dim: 5
});
schema.WithField(entity.NewField().WithName("my_vector").
    WithDataType(entity.FieldTypeFloatVector).
    WithDim(5),
)
export vectorField='{
    "fieldName": "my_vector",
    "dataType": "FloatVector",
    "elementTypeParams": {
        "dim": 5
    }
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $primaryField,
        $vectorField
    ]
}"

Il parametro dim nei frammenti di codice sopra riportati indica la dimensionalità degli embeddings vettoriali da contenere nel campo vettoriale. Il valore FLOAT_VECTOR indica che il campo vettoriale contiene un elenco di numeri fluttuanti a 32 bit, che di solito vengono utilizzati per rappresentare gli antilogaritmi:

  • FLOAT16_VECTOR

    Un campo vettoriale di questo tipo contiene un elenco di numeri flottanti a mezza precisione a 16 bit e di solito si applica a scenari di deep learning o di calcolo basato su GPU con limitazioni di memoria o di larghezza di banda.

  • BFLOAT16_VECTOR

    Un campo vettore di questo tipo contiene un elenco di numeri in virgola mobile a 16 bit con precisione ridotta ma con lo stesso intervallo di esponenti di Float32. Questo tipo di dati è comunemente usato in scenari di deep learning, in quanto riduce l'uso della memoria senza incidere significativamente sulla precisione.

  • INT8_VECTOR

    Un campo vettoriale di questo tipo memorizza vettori composti da numeri interi firmati a 8 bit (int8), con ciascun componente compreso tra -128 e 127. Pensato per le architetture di deep learning quantizzate, come ResNet ed EfficientNet, riduce sostanzialmente le dimensioni del modello e aumenta la velocità di inferenza, con una perdita di precisione minima. Nota: questo tipo di vettore è supportato solo per gli indici HNSW.

  • BINARY_VECTOR

    Un campo vettoriale di questo tipo contiene un elenco di 0 e 1. Servono come caratteristiche compatte per rappresentare i dati in scenari di elaborazione delle immagini e di recupero delle informazioni.

  • SPARSE_FLOAT_VECTOR

    Un campo vettoriale di questo tipo contiene un elenco di numeri non nulli e i loro numeri di sequenza per rappresentare incorporazioni vettoriali rade.

Aggiungere campi scalari

Nei casi più comuni, è possibile utilizzare campi scalari per memorizzare i metadati delle incorporazioni vettoriali memorizzate in Milvus e condurre ricerche ANN con filtraggio dei metadati per migliorare la correttezza dei risultati della ricerca. Milvus supporta diversi tipi di campi scalari, tra cui VarChar, Boolean, Int, Float e Double.

Aggiungere campi stringa

In Milvus è possibile utilizzare campi VarChar per memorizzare stringhe. Per maggiori informazioni sul campo VarChar, consultare Campo stringa.

schema.add_field(
    field_name="my_varchar",
    datatype=DataType.VARCHAR,
    max_length=512
)
schema.addField(AddFieldReq.builder()
        .fieldName("my_varchar")
        .dataType(DataType.VarChar)
        .maxLength(512)
        .build());
schema.push({
    name: "my_varchar",
    data_type: DataType.VarChar,
    max_length: 512
});
schema.WithField(entity.NewField().WithName("my_varchar").
    WithDataType(entity.FieldTypeVarChar).
    WithMaxLength(512),
)
export varCharField='{
    "fieldName": "my_varchar",
    "dataType": "VarChar",
    "elementTypeParams": {
        "max_length": 512
    }
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $primaryField,
        $vectorField,
        $varCharField
    ]
}"

Aggiungere campi numerici

I tipi di numeri supportati da Milvus sono Int8, Int16, Int32, Int64, Float e Double. Per ulteriori informazioni sui campi numerici, consultare Campo numerico.

schema.add_field(
    field_name="my_int64",
    datatype=DataType.INT64,
)
schema.addField(AddFieldReq.builder()
        .fieldName("my_int64")
        .dataType(DataType.Int64)
        .build());
schema.push({
    name: "my_int64",
    data_type: DataType.Int64,
});
schema.WithField(entity.NewField().WithName("my_int64").
    WithDataType(entity.FieldTypeInt64),
)
export int64Field='{
    "fieldName": "my_int64",
    "dataType": "Int64"
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $primaryField,
        $vectorField,
        $varCharField,
        $int64Field
    ]
}"

Aggiungere campi booleani

Milvus supporta i campi booleani. I seguenti frammenti di codice mostrano come aggiungere un campo booleano.

schema.add_field(
    field_name="my_bool",
    datatype=DataType.BOOL,
)
schema.addField(AddFieldReq.builder()
        .fieldName("my_bool")
        .dataType(DataType.Bool)
        .build());
schema.push({
    name: "my_bool",
    data_type: DataType.Boolean,
});
schema.WithField(entity.NewField().WithName("my_bool").
    WithDataType(entity.FieldTypeBool),
)
export boolField='{
    "fieldName": "my_bool",
    "dataType": "Boolean"
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $primaryField,
        $vectorField,
        $varCharField,
        $int64Field,
        $boolField
    ]
}"

Aggiungere campi composti

In Milvus, un campo composito è un campo che può essere suddiviso in sottocampi più piccoli, come le chiavi di un campo JSON o gli indici di un campo Array.

Aggiungere campi JSON

Un campo JSON di solito memorizza dati JSON semistrutturati. Per maggiori informazioni sui campi JSON, consultare Campo JSON.

schema.add_field(
    field_name="my_json",
    datatype=DataType.JSON,
)
schema.addField(AddFieldReq.builder()
        .fieldName("my_json")
        .dataType(DataType.JSON)
        .build());
schema.push({
    name: "my_json",
    data_type: DataType.JSON,
});
schema.WithField(entity.NewField().WithName("my_json").
    WithDataType(entity.FieldTypeJSON),
)
export jsonField='{
    "fieldName": "my_json",
    "dataType": "JSON"
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $primaryField,
        $vectorField,
        $varCharField,
        $int64Field,
        $boolField,
        $jsonField
    ]
}"

Aggiungere campi array

Un campo array memorizza un elenco di elementi. I tipi di dati di tutti gli elementi di un campo array devono essere gli stessi. Per ulteriori informazioni sui campi array, consultare Campo array.

schema.add_field(
    field_name="my_array",
    datatype=DataType.ARRAY,
    element_type=DataType.VARCHAR,
    max_capacity=5,
    max_length=512,
)
schema.addField(AddFieldReq.builder()
        .fieldName("my_array")
        .dataType(DataType.Array)
        .elementType(DataType.VarChar)
        .maxCapacity(5)
        .maxLength(512)
        .build());
schema.push({
    name: "my_array",
    data_type: DataType.Array,
    element_type: DataType.VarChar,
    max_capacity: 5,
    max_length: 512
});
schema.WithField(entity.NewField().WithName("my_array").
    WithDataType(entity.FieldTypeArray).
    WithElementType(entity.FieldTypeInt64).
    WithMaxLength(512).
    WithMaxCapacity(5),
)
export arrayField='{
    "fieldName": "my_array",
    "dataType": "Array",
    "elementDataType": "VarChar",
    "elementTypeParams": {
        "max_length": 512
    }
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $primaryField,
        $vectorField,
        $varCharField,
        $int64Field,
        $boolField,
        $jsonField,
        $arrayField
    ]
}"