Usando o conector Elasticsearch (versão prévia)
Aviso
A funcionalidade semântica do Repositório de Vetores kernel está em versão prévia e melhorias que exigem alterações significativas ainda podem ocorrer em circunstâncias limitadas antes do lançamento.
Visão geral
O conector do Elasticsearch Vector Store pode ser usado para acessar e gerenciar dados no Elasticsearch. O conector tem as seguintes características.
Área de Funcionalidade | Apoio |
---|---|
A coleção é mapeada para | Índice Elasticsearch |
Tipos de propriedade de chave com suporte | corda |
Tipos de propriedade de dados com suporte | Todos os tipos que são compatíveis com System.Text.Json (seja nativamente ou usando um conversor personalizado) |
Tipos de propriedades de vetor suportados |
|
Tipos de índice com suporte |
|
Funções de distância suportadas |
|
Cláusulas de filtro com suporte |
|
Dá suporte a vários vetores em um registro | Sim |
Há suporte para o IsFilterable? | Sim |
Há suporte para o IsFullTextSearchable? | Sim |
StoragePropertyName é suportado? | Não, use JsonSerializerOptions e JsonPropertyNameAttribute em vez disso.
Veja aqui para obter mais informações. |
Começando
Para executar o Elasticsearch localmente para desenvolvimento local ou teste, execute o script start-local
com um comando:
curl -fsSL https://elastic.co/start-local | sh
Adicione o pacote NuGet do conector do Elasticsearch Vector Store ao seu projeto.
dotnet add package Elastic.SemanticKernel.Connectors.Elasticsearch --prerelease
Você pode adicionar o repositório de vetores ao contêiner de injeção de dependência disponível no KernelBuilder
ou ao contêiner de injeção de dependência IServiceCollection
usando métodos de extensão fornecidos pelo Kernel Semântico.
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")));
Métodos de extensão que não têm parâmetros também são fornecidos. Isso requer que uma instância da classe Elastic.Clients.Elasticsearch.ElasticsearchClient
seja registrada de forma distinta no container de injeção de dependência.
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();
Você pode construir uma instância do Elasticsearch Vector Store diretamente.
using Elastic.SemanticKernel.Connectors.Elasticsearch;
using Elastic.Clients.Elasticsearch;
var vectorStore = new ElasticsearchVectorStore(
new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("http://localhost:9200"))));
É possível construir uma referência direta a uma coleção nomeada.
using Elastic.SemanticKernel.Connectors.Elasticsearch;
using Elastic.Clients.Elasticsearch;
var collection = new ElasticsearchVectorStoreRecordCollection<Hotel>(
new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("http://localhost:9200"))),
"skhotels");
Mapeamento de dados
O conector do Elasticsearch usará System.Text.Json.JsonSerializer
para fazer mapeamento.
Como o Elasticsearch armazena documentos com uma chave/id e um valor separados, o mapeador serializará todas as propriedades, exceto a chave para um objeto JSON e a usará como o valor.
O uso do JsonPropertyNameAttribute
é suportado se for necessário um nome de armazenamento diferente do nome da propriedade do modelo de dados. Também é possível usar uma instância personalizada de JsonSerializerOptions
com uma política de nomenclatura de propriedade personalizada. Para habilitar isso, um serializador de origem personalizado deve ser configurado.
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");
Como alternativa, a função lambda DefaultFieldNameInferrer
pode ser configurada para obter o mesmo resultado ou personalizar ainda mais a nomenclatura de propriedade com base em condições dinâmicas.
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");
Como foi escolhida uma política de nomenclatura no formato "SNAKE_CASE" maiúsculo, aqui está um exemplo de como esse tipo de dado será definido no Elasticsearch.
Observe também o uso de JsonPropertyNameAttribute
na propriedade Description
para personalizar ainda mais a nomenclatura de armazenamento.
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
]
}
}
Sem suporte
Não há suporte.
Sem suporte
Não há suporte.