Definindo seu esquema de armazenamento usando uma definição de registro (Visualização)
Aviso
A funcionalidade Semantic Kernel Vetor Store está em pré-visualização, e melhorias que exigem alterações de quebra ainda podem ocorrer em circunstâncias limitadas antes do lançamento.
Descrição geral
Os conectores do Semantic Kernel Vetor Store usam uma abordagem de modelo inicial 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 forma de fornecer essas informações é por meio de definições de registro, que podem ser definidas e fornecidas separadamente ao 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 dict, ou um formato otimizado, como um dataframe e ainda queira aproveitar a funcionalidade de armazenamento vetorial.
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 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 da propriedade de registro
VectorStoreRecordKeyProperty
Use essa classe para indicar que sua propriedade é a chave do registro.
new VectorStoreRecordKeyProperty("HotelId", typeof(ulong)),
Definições de configuração de VectorStoreRecordKeyProperty
Parâmetro | Necessário | Description |
---|---|---|
DataModelPropertyName | Sim | O nome da propriedade no modelo de dados. Usado pelos mapeadores integrados 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 integrados 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. Note que este parâmetro não é suportado por todos os conectores, por exemplo, onde alternativas como JsonPropertyNameAttribute é suportado. |
Gorjeta
Para obter mais informações sobre quais conectores suportam StoragePropertyName e quais alternativas estão disponíveis, consulte a documentação de cada conector.
VectorStoreRecordDataProperty
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 | Necessário | Description |
---|---|---|
DataModelPropertyName | Sim | O nome da propriedade no modelo de dados. Usado pelos mapeadores integrados 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 integrados 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. A predefinição é falsa. |
IsFullTextSearchable | Não | Indica se a propriedade deve ser indexada para pesquisa de texto completo para bancos de dados que oferecem suporte à pesquisa de texto completo. A predefinição é falsa. |
StoragePropertyName | Não | Pode ser usado para fornecer um nome alternativo para a propriedade no banco de dados. Note que este parâmetro não é suportado por todos os conectores, por exemplo, onde alternativas como JsonPropertyNameAttribute é suportado. |
Gorjeta
Para obter mais informações sobre quais conectores suportam 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 de VectorStoreRecordVectorProperty
Parâmetro | Necessário | Description |
---|---|---|
DataModelPropertyName | Sim | O nome da propriedade no modelo de dados. Usado pelos mapeadores integrados 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 integrados para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
Dimensões | Sim para criar coleção, opcional caso contrário | O número de dimensões que o vetor tem. Isso geralmente é 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 armazenamento vetorial. |
Função DistânciaDistância | Não | O tipo de função de distância a ser usada ao fazer a comparação vetorial durante a pesquisa vetorial sobre esse vetor. O padrão varia de acordo com o tipo de armazenamento vetorial. |
StoragePropertyName | Não | Pode ser usado para fornecer um nome alternativo para a propriedade no banco de dados. Note que este parâmetro não é suportado por todos os conectores, por exemplo, onde alternativas como JsonPropertyNameAttribute é suportado. |
Gorjeta
Para obter mais informações sobre quais conectores suportam 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 pandas.
Nota
Os mesmos campos que na 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 ditado com o nome.
Há algumas coisas importantes a observar, 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 registo para um get
e um ou mais para um get_batch
. Quando você quer 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.
O segundo é a adição dos métodos andfrom_dict
, que são usados para converter entre o modelo de dados e o esquema de to_dict
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 e 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
ditado) e digitar para cada propriedade em seu esquema, já que 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 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 de VectorStoreRecordKeyField
Parâmetro | Necessário | Description |
---|---|---|
nome | Sim | O nome do campo no modelo de dados. Usado pelos mapeadores integrados 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 integrados para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
nome_do_armazenamento | Não | Pode ser usado para fornecer um nome alternativo para o campo no banco de dados. Observe que este parâmetro não é suportado por todos os conectores, por exemplo, onde Jackson é usado, nesse caso, o nome do armazenamento pode ser especificado usando anotações Jackson. |
Gorjeta
Para obter mais informações sobre quais conectores suportam 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 de VectorStoreRecordDataField
Parâmetro | Necessário | Description |
---|---|---|
nome | Sim | O nome do campo no modelo de dados. Usado pelos mapeadores integrados 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 integrados 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. A predefinição é falsa. |
isFullTextSearchable | Não | Indica se o campo deve ser indexado para pesquisa de texto completo para bancos de dados que suportam pesquisa de texto completo. A predefinição é falsa. |
nome_do_armazenamento | Não | Pode ser usado para fornecer um nome alternativo para o campo no banco de dados. Observe que este parâmetro não é suportado por todos os conectores, por exemplo, onde Jackson é usado, nesse caso, o nome do armazenamento pode ser especificado usando anotações Jackson. |
Gorjeta
Para obter mais informações sobre quais conectores suportam 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 de VectorStoreRecordVectorField
Parâmetro | Necessário | Description |
---|---|---|
nome | Sim | O nome do campo no modelo de dados. Usado pelos mapeadores integrados 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 integrados para mapear automaticamente entre o esquema de armazenamento e o modelo de dados e para criar índices. |
dimensões | Sim para criar coleção, opcional caso contrário | O número de dimensões que o vetor tem. Isso geralmente é 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 armazenamento vetorial. |
distanceFunction | Não | O tipo de função de distância a ser usada ao fazer a comparação vetorial durante a pesquisa vetorial sobre esse vetor. O padrão varia de acordo com o tipo de armazenamento vetorial. |
nome_do_armazenamento | Não | Pode ser usado para fornecer um nome alternativo para o campo no banco de dados. Observe que este parâmetro não é suportado por todos os conectores, por exemplo, onde Jackson é usado, nesse caso, o nome do armazenamento pode ser especificado usando anotações Jackson. |
Gorjeta
Para obter mais informações sobre quais conectores suportam storageName e quais alternativas estão disponíveis, consulte a documentação de cada conector.