Partager via


Définition de votre schéma de stockage à l’aide d’une définition d’enregistrement (préversion)

Avertissement

La fonctionnalité de magasin de vecteurs du noyau sémantique est en préversion et des améliorations nécessitant des modifications cassants peuvent toujours se produire dans des circonstances limitées avant la mise en production.

Vue d’ensemble

Les connecteurs de magasin de vecteurs du noyau sémantique utilisent une première approche de modèle pour interagir avec les bases de données et permet d’annoter des modèles de données avec des informations nécessaires pour créer des index ou mapper des données au schéma de base de données.

Une autre façon de fournir ces informations consiste à utiliser des définitions d’enregistrement, qui peuvent être définies et fournies séparément au modèle de données. Cela peut être utile dans plusieurs scénarios :

  • Il peut arriver qu’un développeur souhaite utiliser le même modèle de données avec plusieurs configurations.
  • Il peut arriver que le développeur souhaite stocker des données à l’aide d’un schéma très différent du modèle et souhaite fournir un mappeur personnalisé pour la conversion entre le modèle de données et le schéma de stockage.
  • Il peut y avoir un cas où un développeur souhaite utiliser un type intégré, comme un dicté ou un format optimisé comme un dataframe et souhaite toujours tirer parti de la fonctionnalité de magasin de vecteurs.

Voici un exemple de création d’une définition d’enregistrement.

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 },
    }
};

Lorsque vous créez une définition, vous devez toujours fournir un nom et un type pour chaque propriété de votre schéma, car cela est requis pour la création d’index et le mappage des données.

Pour utiliser la définition, passez-la à la méthode GetCollection.

var collection = vectorStore.GetCollection<ulong, Hotel>("skhotels", hotelDefinition);

Classes de configuration des propriétés d’enregistrement

VectorStoreRecordKeyProperty

Utilisez cette classe pour indiquer que votre propriété est la clé de l’enregistrement.

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

Paramètres de configuration VectorStoreRecordKeyProperty

Paramètre Obligatoire Description
DataModelPropertyName Oui Nom de la propriété sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
PropertyType Oui Type de la propriété sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
StoragePropertyName Non Peut être utilisé pour fournir un autre nom pour la propriété dans la base de données. Notez que ce paramètre n’est pas pris en charge par tous les connecteurs, par exemple lorsque des alternatives comme JsonPropertyNameAttribute celles-ci sont prises en charge.

Conseil

Pour plus d’informations sur les connecteurs qui prennent en charge StoragePropertyName et les alternatives disponibles, reportez-vous à la documentation de chaque connecteur.

VectorStoreRecordDataProperty

Utilisez cette classe pour indiquer que votre propriété contient des données générales qui ne sont pas une clé ou un vecteur.

new VectorStoreRecordDataProperty("HotelName", typeof(string)) { IsFilterable = true },

Paramètres de configuration VectorStoreRecordDataProperty

Paramètre Obligatoire Description
DataModelPropertyName Oui Nom de la propriété sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
PropertyType Oui Type de la propriété sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
IsFilterable Non Indique si la propriété doit être indexée pour le filtrage dans les cas où une base de données nécessite d’opter pour l’indexation par propriété. La valeur par défaut est false.
IsFullTextSearchable Non Indique si la propriété doit être indexée pour la recherche en texte intégral pour les bases de données qui prennent en charge la recherche en texte intégral. La valeur par défaut est false.
StoragePropertyName Non Peut être utilisé pour fournir un autre nom pour la propriété dans la base de données. Notez que ce paramètre n’est pas pris en charge par tous les connecteurs, par exemple lorsque des alternatives comme JsonPropertyNameAttribute celles-ci sont prises en charge.

Conseil

Pour plus d’informations sur les connecteurs qui prennent en charge StoragePropertyName et les alternatives disponibles, reportez-vous à la documentation de chaque connecteur.

VectorStoreRecordVectorProperty

Utilisez cette classe pour indiquer que votre propriété contient un vecteur.

new VectorStoreRecordVectorProperty("DescriptionEmbedding", typeof(float)) { Dimensions = 4, DistanceFunction = DistanceFunction.CosineDistance, IndexKind = IndexKind.Hnsw },

Paramètres de configuration VectorStoreRecordVectorProperty

Paramètre Obligatoire Description
DataModelPropertyName Oui Nom de la propriété sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
PropertyType Oui Type de la propriété sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
Dimensions Oui pour la création d’une collection, facultatif sinon Nombre de dimensions dont le vecteur a. Cela est généralement nécessaire lors de la création d’un index vectoriel pour une collection.
IndexKind Non Type d’index avec lequel indexer le vecteur. La valeur par défaut varie selon le type de magasin de vecteurs.
DistanceFunction Non Type de fonction de distance à utiliser lors de la comparaison de vecteurs pendant la recherche vectorielle sur ce vecteur. La valeur par défaut varie selon le type de magasin de vecteurs.
StoragePropertyName Non Peut être utilisé pour fournir un autre nom pour la propriété dans la base de données. Notez que ce paramètre n’est pas pris en charge par tous les connecteurs, par exemple lorsque des alternatives comme JsonPropertyNameAttribute celles-ci sont prises en charge.

Conseil

Pour plus d’informations sur les connecteurs qui prennent en charge StoragePropertyName et les alternatives disponibles, reportez-vous à la documentation de chaque connecteur.

Voici un exemple de création d’une définition d’enregistrement, à utiliser avec un DataFrame pandas.

Remarque

Les mêmes champs que dans la définition du modèle de données sont utilisés ici, pour un datamodel, ils sont ajoutés en tant qu’annotations, ici sous la forme d’une dictée portant le nom.

Il y a quelques points importants à noter, puis les définitions de champs elles-mêmes. Le premier est le container_mode paramètre. Lorsqu’il est défini sur True, cela indique que le modèle de données est un type de conteneur, comme un DataFrame, et que le modèle de données est donc un conteneur d’enregistrements, au lieu d’un seul, un enregistrement conteneur peut être utilisé de la même façon, la principale différence est que get et get_batch retournera le même type de données, avec un enregistrement unique pour un get ou plusieurs pour un get_batch. Lorsque vous souhaitez effectuer un upsert upsert et upsert_batch que vous pouvez utiliser indifféremment, en d’autres termes, le passage d’un conteneur pour upsert entraîner plusieurs upserts, au lieu d’un seul.

Le deuxième est l’ajout des méthodes et from_dict des to_dict méthodes utilisées pour effectuer la conversion entre le modèle de données et le schéma de stockage. Dans ce cas, la to_dict méthode est utilisée pour convertir le DataFrame en une liste d’enregistrements, et la from_dict méthode est utilisée pour convertir une liste d’enregistrements en dataFrame. Il peut également y avoir une serialize deserialize méthode (non illustrée dans l’exemple ci-dessous), pour plus d’informations sur la différence entre celles-ci, consultez la documentation de sérialisation.

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),
)

Lors de la création d’une définition, vous devez toujours fournir un nom (comme clé dans le fields dict) et taper pour chaque propriété de votre schéma, car cela est requis pour la création d’index et le mappage des données.

Pour utiliser la définition, passez-la à la méthode GetCollection ou à un constructeur de collection, ainsi qu’au type de modèle de données.

collection = vector_store.get_collection(
    collection_name="skhotels", 
    data_model_type=pd.DataFrame, 
    data_model_definition=hotel_definition,
)

Voici un exemple de création d’une définition d’enregistrement.

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()
    )
);

Lorsque vous créez une définition, vous devez toujours fournir un nom et un type pour chaque champ de votre schéma, car cela est requis pour la création d’index et le mappage de données.

Pour utiliser la définition, passez-la à la méthode GetCollection.

var collection = vectorStore.getCollection("skhotels",
        JDBCVectorStoreRecordCollectionOptions.builder()
            .withRecordDefinition(hotelDefinition)
            .build()
    );

Classes de configuration de champ d’enregistrement

VectorStoreRecordKeyField

Utilisez cette classe pour indiquer que votre champ est la clé de l’enregistrement.

VectorStoreRecordKeyField.builder().withName("hotelId").withFieldType(String.class).build(),

Paramètres de configuration VectorStoreRecordKeyField

Paramètre Obligatoire Description
name Oui Nom du champ sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
fieldType Oui Type du champ sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
storageName Non Peut être utilisé pour fournir un autre nom pour le champ de la base de données. Notez que ce paramètre n’est pas pris en charge par tous les connecteurs, par exemple, où Jackson est utilisé, dans ce cas, le nom de stockage peut être spécifié à l’aide d’annotations Jackson.

Conseil

Pour plus d’informations sur les connecteurs qui prennent en charge storageName et les alternatives disponibles, reportez-vous à la documentation de chaque connecteur.

VectorStoreRecordDataField

Utilisez cette classe pour indiquer que votre propriété contient des données générales qui ne sont pas une clé ou un vecteur.

VectorStoreRecordDataField.builder()
    .withName("name")
    .withFieldType(String.class)
    .isFilterable(true).build(),

Paramètres de configuration VectorStoreRecordDataField

Paramètre Obligatoire Description
name Oui Nom du champ sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
fieldType Oui Type du champ sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
isFilterable Non Indique si le champ doit être indexé pour le filtrage dans les cas où une base de données nécessite l’inscription à l’indexation par champ. La valeur par défaut est false.
isFullTextSearchable Non Indique si le champ doit être indexé pour la recherche en texte intégral pour les bases de données qui prennent en charge la recherche en texte intégral. La valeur par défaut est false.
storageName Non Peut être utilisé pour fournir un autre nom pour le champ de la base de données. Notez que ce paramètre n’est pas pris en charge par tous les connecteurs, par exemple, où Jackson est utilisé, dans ce cas, le nom de stockage peut être spécifié à l’aide d’annotations Jackson.

Conseil

Pour plus d’informations sur les connecteurs qui prennent en charge storageName et les alternatives disponibles, reportez-vous à la documentation de chaque connecteur.

VectorStoreRecordVectorField

Utilisez cette classe pour indiquer que votre champ contient un vecteur.

VectorStoreRecordVectorField.builder().withName("descriptionEmbedding")
    .withDimensions(4)
    .withIndexKind(IndexKind.HNSW)
    .withDistanceFunction(DistanceFunction.COSINE_DISTANCE)
    .withFieldType(List.class).build(),

Paramètres de configuration VectorStoreRecordVectorField

Paramètre Obligatoire Description
name Oui Nom du champ sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
fieldType Oui Type du champ sur le modèle de données. Utilisé par les mappeurs intégrés pour mapper automatiquement entre le schéma de stockage et le modèle de données et pour créer des index.
dimensions Oui pour la création d’une collection, facultatif sinon Nombre de dimensions dont le vecteur a. Cela est généralement nécessaire lors de la création d’un index vectoriel pour une collection.
indexKind Non Type d’index avec lequel indexer le vecteur. La valeur par défaut varie selon le type de magasin de vecteurs.
distanceFunction Non Type de fonction de distance à utiliser lors de la comparaison de vecteurs pendant la recherche vectorielle sur ce vecteur. La valeur par défaut varie selon le type de magasin de vecteurs.
storageName Non Peut être utilisé pour fournir un autre nom pour le champ de la base de données. Notez que ce paramètre n’est pas pris en charge par tous les connecteurs, par exemple, où Jackson est utilisé, dans ce cas, le nom de stockage peut être spécifié à l’aide d’annotations Jackson.

Conseil

Pour plus d’informations sur les connecteurs qui prennent en charge storageName et les alternatives disponibles, reportez-vous à la documentation de chaque connecteur.