Explicação do esquema

Um esquema define a estrutura de dados de uma coleção. Antes de criar uma coleção, é necessário conceber o respetivo esquema. Esta página ajuda-o a compreender o esquema de coleção e a conceber um exemplo de esquema por si próprio.

Descrição geral

No Milvus, um esquema de coleção reúne uma tabela numa base de dados relacional, que define a forma como o Milvus organiza os dados na coleção.

Um esquema bem concebido é essencial, uma vez que abstrai o modelo de dados e decide se é possível atingir os objectivos comerciais através de uma pesquisa. Além disso, uma vez que cada linha de dados inserida na coleção deve seguir o esquema, ajuda a manter a consistência dos dados e a qualidade a longo prazo. De uma perspetiva técnica, um esquema bem definido leva a um armazenamento de dados de coluna bem organizado e a uma estrutura de índice mais limpa, aumentando o desempenho da pesquisa.

Um esquema de coleção tem uma chave primária, pelo menos um campo vetorial e vários campos escalares. O diagrama a seguir ilustra como mapear um artigo para uma lista de campos de esquema.

Schema Design Anatomy Anatomia do desenho do esquema

A conceção do modelo de dados de um sistema de pesquisa envolve a análise das necessidades comerciais e a abstração da informação num modelo de dados expresso por um esquema. Por exemplo, a pesquisa de um pedaço de texto deve ser "indexada" convertendo a cadeia literal num vetor através da "incorporação" e permitindo a pesquisa vetorial. Para além deste requisito essencial, pode ser necessário armazenar outras propriedades, como o carimbo temporal da publicação e o autor. Estes metadados permitem que as pesquisas semânticas sejam refinadas através de filtragem, devolvendo apenas textos publicados após uma data específica ou por um determinado autor. Também pode obter estes escalares com o texto principal para apresentar o resultado da pesquisa na aplicação. A cada um deles deve ser atribuído um identificador único para organizar estas partes de texto, expresso como um número inteiro ou uma cadeia de caracteres. Esses elementos são essenciais para obter uma lógica de pesquisa sofisticada.

Consulte a secção Prática de conceção de esquemas para saber como criar um esquema bem concebido.

Criar esquema

O seguinte trecho de código demonstra como criar um esquema.

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": []
}'

Adicionar campo primário

O campo primário numa coleção identifica de forma única uma entidade. Só aceita valores Int64 ou VarChar. Os seguintes trechos de código demonstram como adicionar o campo primário.

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
    ]
}'

Ao adicionar um campo, você pode esclarecer explicitamente o campo como o campo primário, definindo sua propriedade is_primary como True. Um campo primário aceita valores Int64 por padrão. Neste caso, o valor do campo primário deve ser um número inteiro semelhante a 12345. Se optar por utilizar valores VarChar no campo primário, o valor deve ser uma cadeia de caracteres semelhante a my_entity_1234.

Pode também definir as propriedades autoId para True para que o Milvus atribua automaticamente os valores do campo primário aquando da inserção de dados.

É aconselhável confiar em autoId em todos os casos, a menos que a definição manual de chaves primárias seja benéfica.

Para mais pormenores, consulte Primary Field & AutoId.

Adicionar campos vectoriais

Os campos vectoriais aceitam várias incorporações vectoriais esparsas e densas. No Milvus, é possível adicionar quatro campos vectoriais a uma coleção. Os seguintes trechos de código demonstram como adicionar um campo vetorial.

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
    ]
}"

O parâmetro dim nos trechos de código acima indica a dimensionalidade dos embeddings vetoriais a serem mantidos no campo vetorial. O valor FLOAT_VECTOR indica que o campo vetorial contém uma lista de números flutuantes de 32 bits, que são normalmente utilizados para representar antilogaritmos:

  • FLOAT16_VECTOR

    Um campo vetorial deste tipo contém uma lista de números flutuantes de meia-precisão de 16 bits e aplica-se normalmente a cenários de aprendizagem profunda com restrições de memória ou largura de banda ou de computação baseada em GPU.

  • BFLOAT16_VECTOR

    Um campo vetorial deste tipo contém uma lista de números de vírgula flutuante de 16 bits com precisão reduzida, mas com o mesmo intervalo de expoentes que o Float32. Este tipo de dados é normalmente utilizado em cenários de aprendizagem profunda, uma vez que reduz a utilização de memória sem afetar significativamente a precisão.

  • INT8_VECTOR

    Um campo de vetor deste tipo armazena vectores compostos por números inteiros assinados de 8 bits (int8), com cada componente a variar entre -128 e 127. Adaptado para arquiteturas de aprendizado profundo quantizadas - como ResNet e EfficientNet - ele reduz substancialmente o tamanho do modelo e aumenta a velocidade de inferência, ao mesmo tempo em que incorre em uma perda mínima de precisão. Nota: Este tipo de vetor é suportado apenas para índices HNSW.

  • BINARY_VECTOR

    Um campo de vetor deste tipo contém uma lista de 0s e 1s. Servem como caraterísticas compactas para representar dados em cenários de processamento de imagem e recuperação de informação.

  • SPARSE_FLOAT_VECTOR

    Um campo vetorial deste tipo contém uma lista de números diferentes de zero e os seus números de sequência para representar embeddings vectoriais esparsos.

Adicionar campos escalares

Em casos comuns, pode utilizar campos escalares para armazenar os metadados das incorporações vectoriais armazenadas no Milvus e realizar pesquisas ANN com filtragem de metadados para melhorar a correção dos resultados da pesquisa. O Milvus suporta vários tipos de campos escalares, incluindo VarChar, Boolean, Int, Float e Double.

Adicionar campos String

No Milvus, pode utilizar campos VarChar para armazenar cadeias de caracteres. Para saber mais sobre o campo VarChar, consulte Campo de cadeia de caracteres.

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
    ]
}"

Adicionar campos numéricos

Os tipos de números que o Milvus suporta são Int8, Int16, Int32, Int64, Float, e Double. Para mais informações sobre os campos de números, consulte Campo de números.

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
    ]
}"

Adicionar campos booleanos

O Milvus suporta campos booleanos. Os seguintes trechos de código demonstram como adicionar um 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
    ]
}"

Adicionar campos compostos

Em Milvus, um campo composto é um campo que pode ser dividido em subcampos mais pequenos, como as chaves num campo JSON ou os índices num campo Array.

Adicionar campos JSON

Um campo JSON geralmente armazena dados JSON semi-estruturados. Para saber mais sobre os campos JSON, consulte 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
    ]
}"

Adicionar campos de matriz

Um campo de matriz armazena uma lista de elementos. Os tipos de dados de todos os elementos de um campo de matriz devem ser os mesmos. Para mais informações sobre os campos de matriz, consulte Campo de matriz.

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
    ]
}"