使用 Elasticsearch 连接器 (预览版)

警告

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

概述

Elasticsearch Vector Store 连接器可用于访问和管理 Elasticsearch 中的数据。 连接器具有以下特征。

功能区域 支持
集合映射到 Elasticsearch 索引
支持的键属性类型 字符串
支持的数据属性类型 System.Text.Json 支持的所有类型(内置或使用自定义转换器)
支持的向量属性类型
  • ReadOnlyMemory<float>
  • IEnumerable<float>
支持的索引类型
  • HNSW (32、8 或 4 位)
  • FLAT(32、8 或 4 位)
支持的距离函数
  • 余弦相似度
  • DotProductSimilarity
  • EuclideanDistance
  • MaxInnerProduct
支持的筛选器子句
  • AnyTagEqualTo
  • EqualTo
支持记录中的多个向量 是的
是否支持Filterable? 是的
是否支持FullTextSearchable? 是的
支持的存储属性名称? 否,请改用 JsonSerializerOptionsJsonPropertyNameAttribute有关详细信息,请参阅此处。

开始

若要 在本地运行 Elasticsearch 进行本地开发或测试,请使用一个命令运行 start-local 脚本:

curl -fsSL https://elastic.co/start-local | sh

将 Elasticsearch Vector Store 连接器 NuGet 包添加到项目。

dotnet add package Elastic.SemanticKernel.Connectors.Elasticsearch --prerelease

可以使用语义内核提供的扩展方法将向量存储添加到 KernelBuilder 上可用的依赖项注入容器或 IServiceCollection 依赖项注入容器。

using Microsoft.SemanticKernel;
using Elastic.Clients.Elasticsearch;

// Using Kernel Builder.
var kernelBuilder = Kernel
    .CreateBuilder()
    .AddElasticsearchVectorStore(new ElasticsearchClientSettings(new Uri("http://localhost:9200")));
using Microsoft.SemanticKernel;
using Elastic.Clients.Elasticsearch;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddElasticsearchVectorStore(new ElasticsearchClientSettings(new Uri("http://localhost:9200")));

还提供不带参数的扩展方法。 这些要求将 Elastic.Clients.Elasticsearch.ElasticsearchClient 类的实例单独注册到依赖项注入容器。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Elastic.Clients.Elasticsearch;

// Using Kernel Builder.
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.Services.AddSingleton<ElasticsearchClient>(sp =>
    new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("http://localhost:9200"))));
kernelBuilder.AddElasticsearchVectorStore();
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Elastic.Clients.Elasticsearch;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ElasticsearchClient>(sp =>
    new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("http://localhost:9200"))));
builder.Services.AddElasticsearchVectorStore();

可以直接构造 Elasticsearch Vector Store 实例。

using Elastic.SemanticKernel.Connectors.Elasticsearch;
using Elastic.Clients.Elasticsearch;

var vectorStore = new ElasticsearchVectorStore(
    new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("http://localhost:9200"))));

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

using Elastic.SemanticKernel.Connectors.Elasticsearch;
using Elastic.Clients.Elasticsearch;

var collection = new ElasticsearchVectorStoreRecordCollection<Hotel>(
    new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("http://localhost:9200"))),
    "skhotels");

数据映射

Elasticsearch 连接器将使用 System.Text.Json.JsonSerializer 进行映射。 由于 Elasticsearch 存储具有单独的键/ID 和值的文档,因此映射器将序列化除 JSON 对象的键以外的所有属性,并将其用作值。

如果需要与数据模型属性名称不同的存储名称,则支持使用 JsonPropertyNameAttribute。 还可以使用具有自定义属性命名策略的自定义 JsonSerializerOptions 实例。 若要启用此功能,必须配置自定义源序列化程序。

using Elastic.SemanticKernel.Connectors.Elasticsearch;
using Elastic.Clients.Elasticsearch;
using Elastic.Clients.Elasticsearch.Serialization;
using Elastic.Transport;

var nodePool = new SingleNodePool(new Uri("http://localhost:9200"));
var settings = new ElasticsearchClientSettings(
    nodePool,
    sourceSerializer: (defaultSerializer, settings) =>
        new DefaultSourceSerializer(settings, options => 
            options.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper));
var client = new ElasticsearchClient(settings);

var collection = new ElasticsearchVectorStoreRecordCollection<Hotel>(
    client,
    "skhotelsjson");

或者,可以将 DefaultFieldNameInferrer lambda 函数配置为实现相同的结果,或者根据动态条件进一步自定义属性命名。

using Elastic.SemanticKernel.Connectors.Elasticsearch;
using Elastic.Clients.Elasticsearch;

var settings = new ElasticsearchClientSettings(new Uri("http://localhost:9200"));
settings.DefaultFieldNameInferrer(name => JsonNamingPolicy.SnakeCaseUpper.ConvertName(name));
var client = new ElasticsearchClient(settings);

var collection = new ElasticsearchVectorStoreRecordCollection<Hotel>(
    client,
    "skhotelsjson");

由于选择了蛇大小写上限的命名策略,下面是 Elasticsearch 中如何设置此数据类型的示例。 另请注意,在 Description 属性上使用 JsonPropertyNameAttribute 以进一步自定义存储命名。

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

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

    [VectorStoreRecordData(IsFilterable = true)]
    public string HotelName { get; set; }

    [JsonPropertyName("HOTEL_DESCRIPTION")]
    [VectorStoreRecordData(IsFullTextSearchable = true)]
    public string Description { get; set; }

    [VectorStoreRecordVector(Dimensions: 4, DistanceFunction.CosineSimilarity, IndexKind.Hnsw)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
}
{
  "_index" : "skhotelsjson",
  "_id" : "h1",
  "_source" : {
    "HOTEL_NAME" : "Hotel Happy",
    "HOTEL_DESCRIPTION" : "A place where everyone can be happy.",
    "DESCRIPTION_EMBEDDING" : [
      0.9,
      0.1,
      0.1,
      0.1
    ]
  }
}

不支持

不支持。

不支持

不支持。