Definindo seu esquema de armazenamento usando uma definição de registro (versão prévia)
Aviso
A funcionalidade do Repositório de Vetores do Kernel Semântico está em versão prévia e as melhorias que exigem alterações significativas ainda podem ocorrer em circunstâncias limitadas antes do lançamento.
Visão geral
Os conectores do Repositório de Vetores do Kernel Semântico usam uma abordagem de modelo primeiro para interagir com bancos de dados e permitem anotar modelos de dados com informações necessárias para criar índices ou mapear dados para o esquema de banco de dados.
Outra maneira de fornecer essas informações é por meio de definições de registro, que podem ser definidas e fornecidas separadamente para o modelo de dados. Isso pode ser útil em vários cenários:
- Pode haver um caso em que um desenvolvedor queira usar o mesmo modelo de dados com mais de uma configuração.
- Pode haver um caso em que o desenvolvedor deseja armazenar dados usando um esquema muito diferente do modelo e deseja fornecer um mapeador personalizado para conversão entre o modelo de dados e o esquema de armazenamento.
- Pode haver um caso em que um desenvolvedor queira usar um tipo interno, como um dicionário, ou um formato otimizado, como um dataframe, e ainda queira aproveitar a funcionalidade do repositório de vetores.
Aqui está um exemplo de como criar uma definição de registro.
using Microsoft.Extensions.VectorData;
var hotelDefinition = new VectorStoreRecordDefinition
{
Properties = new List<VectorStoreRecordProperty>
{
new VectorStoreRecordKeyProperty("HotelId", typeof(ulong)),
new VectorStoreRecordDataProperty("HotelName", typeof(string)) { IsFilterable = true },
new VectorStoreRecordDataProperty("Description", typeof(string)) { IsFullTextSearchable = true },
new VectorStoreRecordVectorProperty("DescriptionEmbedding", typeof(float)) { Dimensions = 4, DistanceFunction = DistanceFunction.CosineDistance, IndexKind = IndexKind.Hnsw },
}
};
Ao criar uma definição, você sempre precisa fornecer um nome e um tipo para cada propriedade em seu esquema, pois isso é necessário para a criação de índice e o mapeamento de dados.
Para usar a definição, passe-a para o método GetCollection.
var collection = vectorStore.GetCollection<ulong, Hotel>("skhotels", hotelDefinition);
Classes de configuração de propriedade de registro
Propriedade VectorStoreRecordKey
Use essa classe para indicar que sua propriedade é a chave do registro.
new VectorStoreRecordKeyProperty("HotelId", typeof(ulong)),
Definições de configuração do VectorStoreRecordKeyProperty
Parâmetro | Obrigatório | Descrição |
---|---|---|
DataModelPropertyName | Sim | O nome da propriedade no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
Tipo de propriedade | Sim | O tipo da propriedade no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
StoragePropertyName | Não | Pode ser usado para fornecer um nome alternativo para a propriedade no banco de dados. Observe que esse parâmetro não é compatível com todos os conectores, por exemplo, onde alternativas como JsonPropertyNameAttribute são suportadas. |
Dica
Para obter mais informações sobre quais conectores dão suporte a StoragePropertyName e quais alternativas estão disponíveis, consulte a documentação de cada conector.
Propriedade VectorStoreRecordData
Use essa classe para indicar que sua propriedade contém dados gerais que não são uma chave ou um vetor.
new VectorStoreRecordDataProperty("HotelName", typeof(string)) { IsFilterable = true },
Definições de configuração de VectorStoreRecordDataProperty
Parâmetro | Obrigatório | Descrição |
---|---|---|
DataModelPropertyName | Sim | O nome da propriedade no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
Tipo de propriedade | Sim | O tipo da propriedade no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
IsFilterable | Não | Indica se a propriedade deve ser indexada para filtragem nos casos em que um banco de dados requer a aceitação da indexação por propriedade. Padrão é false |
ÉFullTextSearchable | Não | Indica se a propriedade deve ser indexada para pesquisa de texto completo para bancos de dados que dão suporte à pesquisa de texto completo. Padrão é false |
StoragePropertyName | Não | Pode ser usado para fornecer um nome alternativo para a propriedade no banco de dados. Observe que esse parâmetro não é compatível com todos os conectores, por exemplo, onde alternativas como JsonPropertyNameAttribute são suportadas. |
Dica
Para obter mais informações sobre quais conectores dão suporte a StoragePropertyName e quais alternativas estão disponíveis, consulte a documentação de cada conector.
VectorStoreRecordVectorProperty
Use essa classe para indicar que sua propriedade contém um vetor.
new VectorStoreRecordVectorProperty("DescriptionEmbedding", typeof(float)) { Dimensions = 4, DistanceFunction = DistanceFunction.CosineDistance, IndexKind = IndexKind.Hnsw },
Definições de configuração do VectorStoreRecordVectorProperty
Parâmetro | Obrigatório | Descrição |
---|---|---|
DataModelPropertyName | Sim | O nome da propriedade no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
Tipo de propriedade | Sim | O tipo da propriedade no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
Dimensões | Sim para criação de coleção, caso contrário, opcional | O número de dimensões que o vetor tem. Isso normalmente é necessário ao criar um índice de vetor para uma coleção. |
IndexKind | Não | O tipo de índice com o qual indexar o vetor. O padrão varia de acordo com o tipo de repositório de vetores. |
Função de distância | Não | O tipo de função de distância a ser usada ao fazer a comparação de vetores durante a pesquisa vetorial sobre esse vetor. O padrão varia de acordo com o tipo de repositório de vetores. |
StoragePropertyName | Não | Pode ser usado para fornecer um nome alternativo para a propriedade no banco de dados. Observe que esse parâmetro não é compatível com todos os conectores, por exemplo, onde alternativas como JsonPropertyNameAttribute são suportadas. |
Dica
Para obter mais informações sobre quais conectores dão suporte a StoragePropertyName e quais alternativas estão disponíveis, consulte a documentação de cada conector.
Aqui está um exemplo de como criar uma definição de registro, para uso com um DataFrame do pandas.
Observação
Os mesmos campos da definição do modelo de dados são usados aqui, para um modelo de dados eles são adicionados como anotações, aqui como um dicionário com o nome.
Há algumas coisas importantes a serem observadas, além das próprias definições de campos. O primeiro é o container_mode
parâmetro. Quando definido como True, isso indica que o modelo de dados é um tipo de contêiner, como um DataFrame, e que o modelo de dados é, portanto, um contêiner de registros, em vez de um único, um registro de contêiner pode ser usado exatamente da mesma maneira, a principal diferença é que get
e get_batch
retornará o mesmo tipo de dados, com um único registro para um get
e um ou mais para um get_batch
. Quando você deseja fazer um upsert upsert
e upsert_batch
pode ser usado de forma intercambiável, em outras palavras, passar um contêiner para upsert
resultará em vários upserts, em vez de um único.
A segunda é a adição dos métodos andfrom_dict
, que são usados para converter entre o modelo de to_dict
dados e o esquema de armazenamento. Nesse caso, o to_dict
método é usado para converter o DataFrame em uma lista de registros e o from_dict
método é usado para converter uma lista de registros em um DataFrame. Também pode haver um serialize
método and deserialize
(não mostrado no exemplo abaixo), para obter detalhes sobre a diferença entre eles, consulte a documentação de serialização.
from semantic_kernel.data import (
VectorStoreRecordDataField,
VectorStoreRecordDefinition,
VectorStoreRecordKeyField,
VectorStoreRecordVectorField,
)
hotel_definition = VectorStoreRecordDefinition(
fields={
"hotel_id": VectorStoreRecordKeyField(property_type="str"),
"hotel_name": VectorStoreRecordDataField(property_type="str", is_filterable=True),
"description": VectorStoreRecordDataField(
property_type="str", has_embedding=True, embedding_property_name="description_embedding"
),
"description_embedding": VectorStoreRecordVectorField(property_type="list[float]"),
},
container_mode=True,
to_dict=lambda record, **_: record.to_dict(orient="records"),
from_dict=lambda records, **_: DataFrame(records),
)
Ao criar uma definição, você sempre precisa fornecer um nome (como a chave no fields
dicionário) e digitar para cada propriedade em seu esquema, pois isso é necessário para a criação de índice e mapeamento de dados.
Para usar a definição, passe-a para o método GetCollection ou um construtor de coleção, juntamente com o tipo de modelo de dados.
collection = vector_store.get_collection(
collection_name="skhotels",
data_model_type=pd.DataFrame,
data_model_definition=hotel_definition,
)
Aqui está um exemplo de como criar uma definição de registro.
var hotelDefinition = VectorStoreRecordDefinition.fromFields(
Arrays.asList(
VectorStoreRecordKeyField.builder().withName("hotelId").withFieldType(String.class).build(),
VectorStoreRecordDataField.builder()
.withName("name")
.withFieldType(String.class)
.isFilterable(true).build(),
VectorStoreRecordDataField.builder()
.withName("description")
.withFieldType(String.class)
.isFullTextSearchable(true).build(),
VectorStoreRecordVectorField.builder().withName("descriptionEmbedding")
.withDimensions(4)
.withIndexKind(IndexKind.HNSW)
.withDistanceFunction(DistanceFunction.COSINE_DISTANCE)
.withFieldType(List.class).build()
)
);
Ao criar uma definição, você sempre precisa fornecer um nome e um tipo para cada campo em seu esquema, pois isso é necessário para a criação de índice e o mapeamento de dados.
Para usar a definição, passe-a para o método GetCollection.
var collection = vectorStore.getCollection("skhotels",
JDBCVectorStoreRecordCollectionOptions.builder()
.withRecordDefinition(hotelDefinition)
.build()
);
Classes de configuração do campo de registro
VectorStoreRecordKeyField
Use essa classe para indicar que seu campo é a chave do registro.
VectorStoreRecordKeyField.builder().withName("hotelId").withFieldType(String.class).build(),
Definições de configuração do VectorStoreRecordKeyField
Parâmetro | Obrigatório | Descrição |
---|---|---|
name | Sim | O nome do campo no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
tipo de campo | Sim | O tipo do campo no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
storageName | Não | Pode ser usado para fornecer um nome alternativo para o campo no banco de dados. Observe que esse parâmetro não é suportado por todos os conectores, por exemplo, onde Jackson é usado, nesse caso, o nome de armazenamento pode ser especificado usando anotações Jackson. |
Dica
Para obter mais informações sobre quais conectores dão suporte a storageName e quais alternativas estão disponíveis, consulte a documentação de cada conector.
VectorStoreRecordDataField
Use essa classe para indicar que sua propriedade contém dados gerais que não são uma chave ou um vetor.
VectorStoreRecordDataField.builder()
.withName("name")
.withFieldType(String.class)
.isFilterable(true).build(),
Definições de configuração do VectorStoreRecordDataField
Parâmetro | Obrigatório | Descrição |
---|---|---|
name | Sim | O nome do campo no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
tipo de campo | Sim | O tipo do campo no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
isFiltrável | Não | Indica se o campo deve ser indexado para filtragem nos casos em que um banco de dados requer a aceitação da indexação por campo. Padrão é false |
isFullTextSearchable | Não | Indica se o campo deve ser indexado para pesquisa de texto completo para bancos de dados que dão suporte à pesquisa de texto completo. Padrão é false |
storageName | Não | Pode ser usado para fornecer um nome alternativo para o campo no banco de dados. Observe que esse parâmetro não é suportado por todos os conectores, por exemplo, onde Jackson é usado, nesse caso, o nome de armazenamento pode ser especificado usando anotações Jackson. |
Dica
Para obter mais informações sobre quais conectores dão suporte a storageName e quais alternativas estão disponíveis, consulte a documentação de cada conector.
VectorStoreRecordVectorField
Use essa classe para indicar que seu campo contém um vetor.
VectorStoreRecordVectorField.builder().withName("descriptionEmbedding")
.withDimensions(4)
.withIndexKind(IndexKind.HNSW)
.withDistanceFunction(DistanceFunction.COSINE_DISTANCE)
.withFieldType(List.class).build(),
Definições de configuração do VectorStoreRecordVectorField
Parâmetro | Obrigatório | Descrição |
---|---|---|
name | Sim | O nome do campo no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
tipo de campo | Sim | O tipo do campo no modelo de dados. Usado pelos mapeadores internos para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
dimensões | Sim para criação de coleção, caso contrário, opcional | O número de dimensões que o vetor tem. Isso normalmente é necessário ao criar um índice de vetor para uma coleção. |
tipo de índice | Não | O tipo de índice com o qual indexar o vetor. O padrão varia de acordo com o tipo de repositório de vetores. |
função distância | Não | O tipo de função de distância a ser usada ao fazer a comparação de vetores durante a pesquisa vetorial sobre esse vetor. O padrão varia de acordo com o tipo de repositório de vetores. |
storageName | Não | Pode ser usado para fornecer um nome alternativo para o campo no banco de dados. Observe que esse parâmetro não é suportado por todos os conectores, por exemplo, onde Jackson é usado, nesse caso, o nome de armazenamento pode ser especificado usando anotações Jackson. |
Dica
Para obter mais informações sobre quais conectores dão suporte a storageName e quais alternativas estão disponíveis, consulte a documentação de cada conector.