使用记录定义定义定义存储架构(预览版)

警告

语义内核向量存储功能处于预览状态,需要中断性变更的改进可能仍发生在发布前的有限情况下。

概述

语义内核矢量存储连接器使用模型第一种方法与数据库交互,并允许使用创建索引或将数据映射到数据库架构所需的信息批注数据模型。

提供此信息的另一种方法是通过记录定义,可以单独定义和提供给数据模型。 这在多个方案中非常有用:

  • 在某些情况下,开发人员想要将同一数据模型与多个配置配合使用。
  • 在某些情况下,开发人员希望使用与模型截然不同的架构来存储数据,并想要提供用于在数据模型和存储架构之间进行转换的自定义映射器。
  • 在某些情况下,开发人员想要使用内置类型(如听写)或优化格式(如数据帧),并且仍希望利用矢量存储功能。

下面是有关如何创建记录定义的示例。

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

创建定义时,始终必须为架构中的每个属性提供名称和类型,因为索引创建和数据映射需要这样做。

若要使用定义,请将其传递给 GetCollection 方法。

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

Record 属性配置类

VectorStoreRecordKeyProperty

使用此类指示属性是记录的键。

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

VectorStoreRecordKeyProperty 配置设置

参数 必需 说明
DataModelPropertyName 数据模型上属性的名称。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
PropertyType 数据模型中属性的类型。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
StoragePropertyName 可用于提供数据库中属性的替代名称。 请注意,所有连接器都不支持此参数,例如支持类似替代项 JsonPropertyNameAttribute 的位置。

提示

有关哪些连接器支持 StoragePropertyName 以及可用的替代项的详细信息,请参阅 每个连接器的文档。

VectorStoreRecordDataProperty

使用此类指示属性包含不是键或矢量的常规数据。

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

VectorStoreRecordDataProperty 配置设置

参数 必需 说明
DataModelPropertyName 数据模型上属性的名称。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
PropertyType 数据模型中属性的类型。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
IsFilterable 指示在数据库需要选择按属性编制索引的情况下,是否应为属性编制索引以进行筛选。 默认为 false。
IsFullTextSearchable 指示是否应为支持全文搜索的数据库编制全文搜索的属性编制索引。 默认为 false。
StoragePropertyName 可用于提供数据库中属性的替代名称。 请注意,所有连接器都不支持此参数,例如支持类似替代项 JsonPropertyNameAttribute 的位置。

提示

有关哪些连接器支持 StoragePropertyName 以及可用的替代项的详细信息,请参阅 每个连接器的文档。

VectorStoreRecordVectorProperty

使用此类指示属性包含向量。

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

VectorStoreRecordVectorProperty 配置设置

参数 必需 说明
DataModelPropertyName 数据模型上属性的名称。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
PropertyType 数据模型中属性的类型。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
维度 是用于集合创建,否则为可选 矢量具有的维度数。 为集合创建向量索引时,通常需要这样做。
IndexKind 要为向量编制索引的索引的类型。 默认值因矢量存储类型而异。
DistanceFunction 在此向量搜索期间执行矢量比较时要使用的距离函数的类型。 默认值因矢量存储类型而异。
StoragePropertyName 可用于提供数据库中属性的替代名称。 请注意,所有连接器都不支持此参数,例如支持类似替代项 JsonPropertyNameAttribute 的位置。

提示

有关哪些连接器支持 StoragePropertyName 以及可用的替代项的详细信息,请参阅 每个连接器的文档。

下面是有关如何创建记录定义的示例,用于 pandas 数据帧

注意

此处使用了与数据模型定义相同的字段,对于作为批注添加的数据模型,此处为具有名称的听写。

需要注意几个重要事项,另一些是字段定义本身。 第一个是 container_mode 参数。 如果设置为 True,则表示数据模型是容器类型(如 DataFrame),因此数据模型是记录的容器容器,而不是单个记录,可以采用完全相同的方式使用容器记录,主要区别在于 get ,并将 get_batch 返回相同的数据类型, 具有一条记录, get 一个或多个记录用于一个或多个 get_batch。 如果要执行 upsert, upsert 并且可以 upsert_batch 互换使用,换句话说,传递容器 upsert 将导致多个向上插入,而不是单个插入。

第二种是添加to_dictfrom_dict和方法,用于在数据模型和存储架构之间转换。 在这种情况下, to_dict 该方法用于将 DataFrame 转换为记录列表,并且 from_dict 该方法用于将记录列表转换为 DataFrame。 还可以有一个 serializedeserialize 方法(下面的示例中未显示),有关这些方法之间的差异的详细信息,请参阅 序列化文档

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

创建定义时,始终必须提供名称(作为听写中的 fields 键)和架构中每个属性的类型,因为索引创建和数据映射需要这样做。

若要使用定义,请将其传递给 GetCollection 方法或集合构造函数,以及数据模型类型。

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

下面是有关如何创建记录定义的示例。

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

创建定义时,始终必须为架构中的每个字段提供名称和类型,因为创建索引和数据映射需要这样做。

若要使用定义,请将其传递给 GetCollection 方法。

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

记录字段配置类

VectorStoreRecordKeyField

使用此类指示字段是记录的键。

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

VectorStoreRecordKeyField 配置设置

参数 必需 说明
name 数据模型上字段的名称。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
fieldType 数据模型中字段的类型。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
storageName 可用于为数据库中的字段提供备用名称。 请注意,所有连接器都不支持此参数,例如使用杰克逊的位置,在这种情况下,可以使用 Jackson 注释指定存储名称。

提示

有关哪些连接器支持 storageName 以及哪些替代项可用的详细信息,请参阅 每个连接器的文档。

VectorStoreRecordDataField

使用此类指示属性包含不是键或矢量的常规数据。

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

VectorStoreRecordDataField 配置设置

参数 必需 说明
name 数据模型上字段的名称。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
fieldType 数据模型中字段的类型。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
isFilterable 指示在数据库需要选择为每个字段编制索引的情况下,是否应为字段编制索引以进行筛选。 默认为 false。
isFullTextSearchable 指示是否应为字段编制索引,以便对支持全文搜索的数据库进行全文搜索。 默认为 false。
storageName 可用于为数据库中的字段提供备用名称。 请注意,所有连接器都不支持此参数,例如使用杰克逊的位置,在这种情况下,可以使用 Jackson 注释指定存储名称。

提示

有关哪些连接器支持 storageName 以及哪些替代项可用的详细信息,请参阅 每个连接器的文档。

VectorStoreRecordVectorField

使用此类指示字段包含向量。

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

VectorStoreRecordVectorField 配置设置

参数 必需 说明
name 数据模型上字段的名称。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
fieldType 数据模型中字段的类型。 由内置映射器用来在存储架构和数据模型之间自动映射,以及用于创建索引。
dimensions 是用于集合创建,否则为可选 矢量具有的维度数。 为集合创建向量索引时,通常需要这样做。
indexKind 要为向量编制索引的索引的类型。 默认值因矢量存储类型而异。
distanceFunction 在此向量搜索期间执行矢量比较时要使用的距离函数的类型。 默认值因矢量存储类型而异。
storageName 可用于为数据库中的字段提供备用名称。 请注意,所有连接器都不支持此参数,例如使用杰克逊的位置,在这种情况下,可以使用 Jackson 注释指定存储名称。

提示

有关哪些连接器支持 storageName 以及哪些替代项可用的详细信息,请参阅 每个连接器的文档。