Partilhar via


Defina o seu modelo de dados

Microsoft.Extensions.VectorData utiliza uma abordagem baseada no modelo para interagir com bases de dados.

Todos os métodos para upsert ou obter registos utilizam classes de modelo fortemente tipadas. Existem duas formas de definir o modelo de dados:

  • Decorando propriedades nas classes do modelo com atributos que indicam o propósito de cada propriedade.
  • Ao definir o seu esquema de armazenamento usando uma definição de registo que fornece separadamente do modelo de dados. A definição do registo é um VectorStoreCollectionDefinition que contém propriedades.

Aqui está um exemplo de uma classe, ou modelo de dados, cujas propriedades são decoradas com VectorStore*Attribute atributos.

public class Hotel
{
    [VectorStoreKey]
    public ulong HotelId { get; set; }

    [VectorStoreData(IsIndexed = true)]
    public required string HotelName { get; set; }

    [VectorStoreData(IsFullTextIndexed = true)]
    public required string Description { get; set; }

    [VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }

    [VectorStoreData(IsIndexed = true)]
    public required string[] Tags { get; set; }
}

Atributos das propriedades do modelo de dados

Os VectorStore*Attribute atributos que definem modelos de dados para bases de dados vetoriais são:

VectorStoreKeyAttribute

Use o VectorStoreKeyAttribute atributo para indicar que a sua propriedade é a chave principal do registo.

[VectorStoreKey]
public ulong HotelId { get; set; }

A tabela seguinte mostra os parâmetros para VectorStoreKeyAttribute.

Parâmetro Obrigatório Descrição
StorageName No Pode ser usado para fornecer um nome alternativo para a propriedade na base de dados. Este parâmetro não é suportado por todos os fornecedores, por exemplo, onde alternativas como JsonPropertyNameAttribute o são suportados.

VectorStoreDataAttribute

Use o VectorStoreDataAttribute atributo para indicar que a sua propriedade contém dados gerais que não são uma chave ou um vetor.

[VectorStoreData(IsIndexed = true)]
public required string HotelName { get; set; }

A tabela seguinte mostra os parâmetros para VectorStoreDataAttribute.

Parâmetro Obrigatório Descrição
IsIndexed No Indica se a propriedade deve ser indexada para filtragem nos casos em que uma base de dados exija aderir à indexação por propriedade. A predefinição é false.
IsFullTextIndexed No Indica se a propriedade deve ser indexada para pesquisa de texto integral em bases de dados que suportem pesquisa de texto completo. A predefinição é false.
StorageName No Pode ser usado para fornecer um nome alternativo para a propriedade na base de dados. Este parâmetro não é suportado por todos os fornecedores, por exemplo, quando alternativas como JsonPropertyNameAttribute as são suportadas.

VectorStoreVectorAttribute

Use o VectorStoreVectorAttribute atributo para indicar que a sua propriedade contém um vetor.

[VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }

Também é possível usar VectorStoreVectorAttribute em propriedades que não têm tipo vetorial, por exemplo, uma propriedade do tipo string. Quando uma propriedade é decorada desta forma, é necessário fornecer uma IEmbeddingGenerator instância à loja vetorial. Ao upserar o registo, o texto que está na string propriedade é automaticamente convertido e armazenado como um vetor na base de dados. (Não é possível recuperar um vetor usando este mecanismo.)

[VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
public string DescriptionEmbedding { get; set; }

Sugestão

Para mais informações sobre como usar a geração de embedding incorporada, veja Deixe o vetor armazenar gerar embeddings.

A tabela seguinte mostra os parâmetros para VectorStoreVectorAttribute.

Parâmetro Obrigatório Descrição
Dimensions Sim O número de dimensões que o vetor tem. Isto é necessário ao criar um índice vetorial para uma coleção.
IndexKind No O tipo de índice para indexar o vetor. O padrão varia consoante o tipo de loja vetorial.
DistanceFunction No O tipo de função a usar ao fazer comparação vetorial durante a pesquisa vetorial sobre este vetor. O padrão varia consoante o tipo de loja vetorial.
StorageName No Pode ser usado para fornecer um nome alternativo para a propriedade na base de dados. Este parâmetro não é suportado por todos os fornecedores, por exemplo, quando alternativas como JsonPropertyNameAttribute a são suportadas.

Os tipos comuns de índice e os tipos de função de distância são fornecidos como valores estáticos nas IndexKind classes e.DistanceFunction Implementações individuais de armazenamento vetorial podem também usar os seus próprios tipos de índice e funções de distância, onde a base de dados suporta tipos invulgares.

Propriedades de definição de registo

Use as VectorStore*Property classes para criar uma definição de registo que passe ao modelo de dados:

VectorStoreKeyProperty

Use a VectorStoreKeyProperty classe para indicar que a sua propriedade é a chave do registo.

new VectorStoreKeyProperty("HotelId", typeof(ulong)),

A tabela seguinte mostra as definições de configuração para VectorStoreKeyProperty.

Parâmetro Obrigatório Descrição
Name Sim O nome da propriedade no modelo de dados. Usado pelo mapeador para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices.
Type No O tipo da propriedade no modelo de dados. Usado pelo mapeador para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices.
StorageName No Pode ser usado para fornecer um nome alternativo para a propriedade na base de dados. Este parâmetro não é suportado por todos os fornecedores, por exemplo, quando alternativas como JsonPropertyNameAttribute as são suportadas.

VectorStoreDataProperty

Use a VectorStoreDataProperty classe para indicar que a sua propriedade contém dados gerais que não são uma chave ou um vetor.

new VectorStoreDataProperty("HotelName", typeof(string)) { IsIndexed = true },
new VectorStoreDataProperty("Description", typeof(string)) { IsFullTextIndexed = true },

A tabela seguinte mostra as definições de configuração para VectorStoreDataProperty.

Parâmetro Obrigatório Descrição
Name Sim O nome da propriedade no modelo de dados. Usado pelo mapeador para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices.
Type No O tipo da propriedade no modelo de dados. Usado pelo mapeador para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices.
IsIndexed No Indica se a propriedade deve ser indexada para filtragem nos casos em que uma base de dados exija aderir à indexação por propriedade. O valor padrão é falso.
IsFullTextIndexed No Indica se a propriedade deve ser indexada para pesquisa de texto integral em bases de dados que suportem pesquisa de texto completo. O valor padrão é falso.
StorageName No Pode ser usado para fornecer um nome alternativo para a propriedade na base de dados. Este parâmetro não é suportado por todos os fornecedores, por exemplo, quando alternativas como JsonPropertyNameAttribute a são suportadas.

VectorStoreVectorProperty

Use a VectorStoreVectorProperty classe para indicar que a sua propriedade contém um vetor.

new VectorStoreVectorProperty("DescriptionEmbedding", typeof(float), dimensions: 4)

A tabela seguinte mostra as definições de configuração para VectorStoreVectorProperty.

Parâmetro Obrigatório Descrição
Name Sim O nome da propriedade no modelo de dados. Usado pelo mapeador para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices.
Type No O tipo da propriedade no modelo de dados. Usado pelo mapeador para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices.
Dimensions Sim O número de dimensões que o vetor tem. Isto é necessário para criar um índice vetorial para uma coleção.
IndexKind No O tipo de índice para indexar o vetor. O padrão varia consoante o tipo de loja vetorial.
DistanceFunction No O tipo de função a usar ao fazer comparação vetorial durante a pesquisa vetorial sobre este vetor. O padrão varia consoante o tipo de loja vetorial.
StorageName No Pode ser usado para fornecer um nome alternativo para a propriedade na base de dados. Este parâmetro não é suportado por todos os fornecedores, por exemplo, quando alternativas como JsonPropertyNameAttribute a são suportadas.
EmbeddingGenerator No Permite especificar uma Microsoft.Extensions.AI.IEmbeddingGenerator instância a usar para gerar embeddings automaticamente para a propriedade decorada.

Usar abstrações de armazenamento vetorial sem definir um modelo de dados

Há casos em que não é desejável ou possível definir o seu próprio modelo de dados. Por exemplo, imagine que na altura da compilação não sabe como é o seu esquema de base de dados, e o esquema é fornecido apenas através da configuração. Criar um modelo de dados que reflita o esquema seria impossível neste caso. Em vez disso, pode mapear dinamicamente usando um Dictionary<string, object?> tipo para o registo. As propriedades são adicionadas ao Dictionary com a chave como nome da propriedade e o valor como o valor da propriedade.

Observação

A maioria das aplicações simplesmente usa tipos .NET fortemente digitados para modelar os seus dados. O mapeamento Dictionary<string, object?> dinâmico é para cenários avançados e arbitrários de mapeamento de dados.

Fornecer informação do esquema ao utilizar Dictionary

Quando usa um Dictionary, os fornecedores ainda precisam de saber como é o esquema da base de dados. Sem a informação do esquema, o fornecedor não conseguiria criar uma coleção nem saber como mapear para e a partir da representação de armazenamento que cada base de dados utiliza.

Pode usar uma definição de registo para fornecer a informação do esquema. Ao contrário de um modelo de dados, uma definição de registo pode ser criada a partir da configuração em tempo de execução quando a informação do esquema não é conhecida em tempo de compilação.

Exemplo

Para usar Dictionary com um fornecedor, especifique-o como o seu modelo de dados ao criar a coleção. Também forneça uma definição de registo.

VectorStoreCollectionDefinition definition = new()
{
    Properties =
    [
        new VectorStoreKeyProperty("Key", typeof(string)),
        new VectorStoreDataProperty("Term", typeof(string)),
        new VectorStoreDataProperty("Definition", typeof(string)),
        new VectorStoreVectorProperty("DefinitionEmbedding", typeof(ReadOnlyMemory<float>), dimensions: 1536)
    ]
};

// Use GetDynamicCollection instead of the regular GetCollection method
// to get an instance of a collection using Dictionary<string, object?>.
VectorStoreCollection<object, Dictionary<string, object?>> dynamicDataModelCollection =
    vectorStore.GetDynamicCollection("glossary", definition);

// Since schema information is available from the record definition,
// it's possible to create a collection with the right vectors,
// dimensions, indexes, and distance functions.
await dynamicDataModelCollection.EnsureCollectionExistsAsync();

// When retrieving a record from the collection,
// access key, data, and vector values via the dictionary entries.
Dictionary<string, object?>? record = await dynamicDataModelCollection.GetAsync("SK");
Console.WriteLine(record["Definition"]);