使用 Azure CosmosDB NoSQL 矢量存储连接器(预览版)

警告

Azure CosmosDB NoSQL 矢量存储功能处于预览状态,需要重大更改的改进可能在发布前的有限情况下发生。

警告

语义内核向量存储功能目前处于预览阶段,在发布之前,可能仍会在某些特定情况下进行需要重大更改的改进。

警告

语义内核向量存储功能目前处于预览阶段,在发布之前,可能仍会在某些特定情况下进行需要重大更改的改进。

概述

Azure CosmosDB NoSQL 矢量存储连接器可用于访问和管理 Azure CosmosDB NoSQL 中的数据。 连接器具有以下特征。

功能区域 支持
集合映射到 Azure Cosmos DB NoSQL 容器
支持的键属性类型
  • 字符串
  • CosmosNoSqlCompositeKey
支持的数据属性类型
  • 字符串
  • 整数 (int)
  • 长/久
  • 双倍
  • 浮动
  • 布尔
  • DateTimeOffset (日期时间偏移)
  • 和每种类型的枚举
支持的向量属性类型
  • 只读内存<float>
  • <嵌入浮点>
  • float[]
  • ReadOnlyMemory<字节>
  • <嵌入字节>
  • byte[]
  • ReadOnlyMemory<sbyte>
  • <嵌入 sbyte>
  • sbyte[]
支持的索引类型
  • 平面
  • QuantizedFlat
  • DiskAnn
支持的距离函数
  • 余弦相似度 (Cosine Similarity)
  • 点积相似性 (DotProductSimilarity)
  • EuclideanDistance
支持的过滤条件
  • AnyTagEqualTo
  • EqualTo
支持记录中的多个向量
是否支持 IsIndexed?
是否支持FullTextIndexed?
StorageName支持吗? 否,请改用 JsonSerializerOptionsJsonPropertyNameAttribute有关详细信息,请参阅此处。
支持 HybridSearch?

局限性

手动初始化 CosmosClient 时,必须指定 CosmosClientOptions.UseSystemTextJsonSerializerWithOptions,因为默认序列化程序存在限制。 此选项可以设置为 JsonSerializerOptions.Default 或使用其他序列化程序选项进行自定义以满足特定配置需求。

var cosmosClient = new CosmosClient(connectionString, new CosmosClientOptions()
{
    UseSystemTextJsonSerializerWithOptions = JsonSerializerOptions.Default,
});

入门

将 Azure CosmosDB NoSQL Vector Store 连接器 NuGet 包添加到项目。

dotnet add package Microsoft.SemanticKernel.Connectors.CosmosNoSql --prerelease

可以使用语义内核提供的扩展方法,将向量存储添加到KernelBuilderIServiceCollection所提供的依赖项注入容器中。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;

// Using Kernel Builder.
var kernelBuilder = Kernel
    .CreateBuilder();
kernelBuilder.Services
    .AddCosmosNoSqlVectorStore(connectionString, databaseName);
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCosmosNoSqlVectorStore(connectionString, databaseName);

还提供不带参数的扩展方法。 这些要求将实例 Microsoft.Azure.Cosmos.Database 单独注册到依赖项注入容器。

using System.Text.Json;
using Microsoft.Azure.Cosmos;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;

// Using Kernel Builder.
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.Services.AddSingleton<Database>(
    sp =>
    {
        var cosmosClient = new CosmosClient(connectionString, new CosmosClientOptions()
        {
            // When initializing CosmosClient manually, setting this property is required 
            // due to limitations in default serializer. 
            UseSystemTextJsonSerializerWithOptions = JsonSerializerOptions.Default,
        });

        return cosmosClient.GetDatabase(databaseName);
    });
kernelBuilder.Services.AddCosmosNoSqlVectorStore();
using System.Text.Json;
using Microsoft.Azure.Cosmos;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<Database>(
    sp =>
    {
        var cosmosClient = new CosmosClient(connectionString, new CosmosClientOptions()
        {
            // When initializing CosmosClient manually, setting this property is required 
            // due to limitations in default serializer. 
            UseSystemTextJsonSerializerWithOptions = JsonSerializerOptions.Default,
        });

        return cosmosClient.GetDatabase(databaseName);
    });
builder.Services.AddCosmosNoSqlVectorStore();

可以直接构造 Azure CosmosDB NoSQL 矢量存储实例。

using System.Text.Json;
using Microsoft.Azure.Cosmos;
using Microsoft.SemanticKernel.Connectors.CosmosNoSql;

var cosmosClient = new CosmosClient(connectionString, new CosmosClientOptions()
{
    // When initializing CosmosClient manually, setting this property is required 
    // due to limitations in default serializer. 
    UseSystemTextJsonSerializerWithOptions = JsonSerializerOptions.Default,
});

var database = cosmosClient.GetDatabase(databaseName);
var vectorStore = new CosmosNoSqlVectorStore(database);

可以构造对命名集合的直接引用。

using System.Text.Json;
using Microsoft.Azure.Cosmos;
using Microsoft.SemanticKernel.Connectors.CosmosNoSql;

var cosmosClient = new CosmosClient(connectionString, new CosmosClientOptions()
{
    // When initializing CosmosClient manually, setting this property is required 
    // due to limitations in default serializer. 
    UseSystemTextJsonSerializerWithOptions = JsonSerializerOptions.Default,
});

var database = cosmosClient.GetDatabase(databaseName);
var collection = new CosmosNoSqlCollection<string, Hotel>(
    database,
    "skhotels");

数据映射

Azure CosmosDB NoSQL Vector Store 连接器在从数据模型映射到存储时提供默认映射器。

此映射器将数据模型上的属性列表直接转换为 Azure CosmosDB NoSQL 中的字段,并用于 System.Text.Json.JsonSerializer 转换为存储架构。 这意味着,如果需要与数据模型属性名称不同的存储名称,则支持使用该 JsonPropertyNameAttribute 名称。 唯一的例外是记录的键,这个键被映射到一个名为 id 的数据库字段,因为所有 CosmosDB NoSQL 记录必须使用此名称作为其 ID。

还可以使用具有自定义属性命名策略的自定义 JsonSerializerOptions 实例。 若要启用此功能,必须在构造过程中将 JsonSerializerOptions 传递到 CosmosNoSqlCollection

using System.Text.Json;
using Microsoft.Azure.Cosmos;
using Microsoft.SemanticKernel.Connectors.CosmosNoSql;

var jsonSerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper };

var cosmosClient = new CosmosClient(connectionString, new CosmosClientOptions()
{
    // When initializing CosmosClient manually, setting this property is required 
    // due to limitations in default serializer. 
    UseSystemTextJsonSerializerWithOptions = jsonSerializerOptions
});

var database = cosmosClient.GetDatabase(databaseName);
var collection = new CosmosNoSqlCollection<string, Hotel>(
    database,
    "skhotels",
    new() { JsonSerializerOptions = jsonSerializerOptions });

使用上述自定义JsonSerializerOptionsSnakeCaseUpper,以下数据模型将映射到下面的JSON。

using System.Text.Json.Serialization;
using Microsoft.Extensions.VectorData;

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

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

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

    [JsonPropertyName("HOTEL_DESCRIPTION_EMBEDDING")]
    [VectorStoreVector(4, DistanceFunction = DistanceFunction.EuclideanDistance, IndexKind = IndexKind.QuantizedFlat)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
}
{
    "id": "1",
    "HOTEL_NAME": "Hotel Happy",
    "DESCRIPTION": "A place where everyone can be happy.",
    "HOTEL_DESCRIPTION_EMBEDDING": [0.9, 0.1, 0.1, 0.1],
}

使用分区键

在 Azure Cosmos DB for NoSQL 连接器中,分区键属性默认设置为键属性 - idPartitionKeyPropertyName 类中的 CosmosNoSqlCollectionOptions 属性允许将其他属性指定为分区键。

CosmosNoSqlCollection 类支持两种键类型:stringCosmosNoSqlCompositeKeyCosmosNoSqlCompositeKeyRecordKeyPartitionKey组成。

如果未设置分区键属性(并使用默认键属性),string 键可用于使用数据库记录的操作。 但是,如果指定了分区键属性,建议使用 CosmosNoSqlCompositeKey 来提供键值和分区键值。

指定分区键属性名称:

var options = new CosmosNoSqlCollectionOptions
{
    PartitionKeyPropertyName = nameof(Hotel.HotelName)
};

var collection = new CosmosNoSqlCollection<string, Hotel>(database, "collection-name", options) 
    as VectorStoreCollection<CosmosNoSqlCompositeKey, Hotel>;

使用分区键获取:

var record = await collection.GetAsync(new CosmosNoSqlCompositeKey("hotel-id", "hotel-name"));

概述

Azure CosmosDB NoSQL 矢量存储连接器可用于访问和管理 Azure CosmosDB NoSQL 中的数据。 连接器具有以下特征。

功能区域 支持
集合映射到 Azure Cosmos DB NoSQL 容器
支持的键属性类型
  • 字符串
  • AzureCosmosDBNoSQLCompositeKey
支持的数据属性类型
  • 字符串
  • 整数 (int)
  • 长/久
  • 双倍
  • 浮动
  • 布尔
  • DateTimeOffset (日期时间偏移)
  • 和这些类型中的每一种的可迭代对象
支持的向量属性类型
  • list[float]
  • 列表[整数]
  • ndarray
支持的索引类型
  • 平面
  • QuantizedFlat
  • DiskAnn
支持的距离函数
  • 余弦相似度 (Cosine Similarity)
  • 点积相似性 (DotProductSimilarity)
  • EuclideanDistance
支持的过滤条件
  • AnyTagEqualTo
  • EqualTo
支持记录中的多个向量
is_filterable 受支持?
“is_full_text_searchable” 功能受支持吗?
支持 HybridSearch?

入门

将 Azure 额外包添加到项目。

pip install semantic-kernel[azure]

接下来,可以直接创建 Azure CosmosDB NoSQL 矢量存储实例。 这会读取某些环境变量以配置与 Azure CosmosDB NoSQL 的连接:

  • AZURE_COSMOS_DB_NO_SQL_URL
  • AZURE_COSMOS_DB_NO_SQL_DATABASE_NAME

(可选):

  • AZURE_COSMOS_DB_NO_SQL_KEY

如果未设置,将使用 AsyncDefaultAzureCredential 进行身份验证。

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLStore

vector_store = AzureCosmosDBNoSQLStore()

还可以在构造函数中提供这些值:

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLStore

vector_store = AzureCosmosDBNoSQLStore(
    url="https://<your-account-name>.documents.azure.com:443/",
    key="<your-account-key>",
    database_name="<your-database-name>"
)

可以传入 CosmosClient 实例,只需确保它是异步客户端。

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLStore
from azure.cosmos.aio import CosmosClient

client = CosmosClient(
    url="https://<your-account-name>.documents.azure.com:443/",
    credential="<your-account-key>" or AsyncDefaultAzureCredential()
)
vector_store = AzureCosmosDBNoSQLStore(
    client=client,
    database_name="<your-database-name>"
)

下一步需要一个数据模型,以下示例中使用了一个名为 Hotels 的变量。

通过商店,您可以获得一个集合:

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLStore

vector_store = AzureCosmosDBNoSQLStore()
collection = vector_store.get_collection(collection_name="skhotels", data_model=Hotel)

可以构造对命名集合的直接引用,这使用与上述相同的环境变量。

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLCollection

collection = AzureCosmosDBNoSQLCollection(
    collection_name="skhotels",
    data_model_type=Hotel,
)

使用分区键

在 Azure Cosmos DB for NoSQL 连接器中,分区键属性默认设置为键属性 - id。 还可以为构造函数中的分区键提供值。

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLCollection

collection = AzureCosmosDBNoSQLCollection(
    collection_name="skhotels",
    data_model_type=Hotel,
    partition_key="hotel_name"
)

使用 PartitionKey 对象时,这可以是更复杂的键:

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLCollection
from azure.cosmos import PartitionKey

partition_key = PartitionKey(path="/hotel_name")
collection = AzureCosmosDBNoSQLCollection(
    collection_name="skhotels",
    data_model_type=Hotel,
    partition_key=partition_key
)

AzureCosmosDBNoSQLVectorStoreRecordCollection 类支持两种键类型:stringAzureCosmosDBNoSQLCompositeKeyAzureCosmosDBNoSQLCompositeKeykeypartition_key组成。

如果未设置分区键属性(并使用默认键属性),string 键可用于使用数据库记录的操作。 但是,如果指定了分区键属性,建议使用 AzureCosmosDBNoSQLCompositeKeygetdelete 方法提供键和分区键值。

from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLCollection
from semantic_kernel.connectors.memory.azure_cosmos_db import AzureCosmosDBNoSQLCompositeKey
from semantic_kernel.data import VectorStoreRecordDataField

@vectorstoremodel
class data_model_type:
    id: Annotated[str, VectorStoreRecordKeyField]
    product_type: Annotated[str, VectorStoreRecordDataField()]
    ...

collection = store.get_collection(
    collection_name=collection_name,
    data_model=data_model_type,
    partition_key=PartitionKey(path="/product_type"),
)

# when there is data in the collection
composite_key = AzureCosmosDBNoSQLCompositeKey(
    key='key value', partition_key='partition key value'
)
# get a record, with the partition key
record = await collection.get(composite_key)

# or delete
await collection.delete(composite_key)

即将推出

更多信息即将推出。