Поделиться через


Использование соединителя Elasticsearch (предварительная версия)

Предупреждение

Функции векторного хранилища семантического ядра доступны в предварительной версии, и улучшения, требующие критических изменений, по-прежнему могут возникать в ограниченных случаях перед выпуском.

Обзор

Соединитель Elasticsearch Vector Store можно использовать для доступа к данным и управления ими в Elasticsearch. Соединитель имеет следующие характеристики.

Область функций Поддержка
Коллекция сопоставляется с Индекс Elasticsearch
Поддерживаемые типы свойств ключей струна
Поддерживаемые типы свойств данных Все типы, поддерживаемые System.Text.Json (встроенные или с помощью пользовательского преобразователя)
Поддерживаемые типы свойств вектора
  • Память только для чтения<float>
  • IEnumerable<float>
Поддерживаемые типы индексов
  • HNSW (32, 8 или 4-разрядная версия)
  • FLAT (32, 8 или 4 бита)
Поддерживаемые функции расстояния
  • CosineSimilarity
  • DotProductSimilarity
  • EuclideanDistance
  • MaxInnerProduct
Поддерживаемые условия фильтров
  • AnyTagEqualTo
  • EqualTo
Поддержка нескольких векторов в записи Да
Поддерживается IsFilterable? Да
Поддерживается ЛиFullTextSearchable? Да
Поддерживается StoragePropertyName? Нет, используйте вместо этого JsonSerializerOptions и JsonPropertyNameAttribute. дополнительные сведения см. здесь.

Начало работы

Чтобы запустить Elasticsearch локально для локальной разработки или тестирования, выполните скрипт start-local с одной командой:

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

Добавьте в проект пакет NuGet коннектора Elasticsearch Vector Store.

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 хранит документы с отдельным ключом или идентификатором и значением, приложение mapper сериализует все свойства, кроме ключа в объект 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 для достижения того же результата или для еще большей настройки именования свойств на основе динамических условий.

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

Так как выбрана политика именования в верхнем стиле snake case, вот пример того, как этот тип данных будет задан в Elasticsearch. Кроме того, обратите внимание на использование JsonPropertyNameAttribute в свойстве Description для дальнейшей настройки именования хранилища.

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
    ]
  }
}

Не поддерживается

Не поддерживается.

Не поддерживается

Не поддерживается.