Compartir a través de


Uso del conector de Elasticsearch (versión preliminar)

Advertencia

La funcionalidad de la Tienda de Vectores del Kernel Semántico está en vista previa, y las mejoras que requieren cambios importantes pueden ocurrir en circunstancias limitadas antes del lanzamiento final.

Visión general

El conector del almacén de vectores de Elasticsearch se puede usar para acceder a los datos y administrarlos en Elasticsearch. El conector tiene las siguientes características.

Área de funciones Apoyo
La colección se asocia con Índice de Elasticsearch
Tipos de propiedades de clave admitidos cuerda
Tipos de propiedad de datos admitidos Todos los tipos admitidos por System.Text.Json (ya sea incorporado o mediante un convertidor personalizado)
Tipos de propiedades vectoriales admitidos
  • ReadOnlyMemory<float>
  • IEnumerable<float>
Tipos de índice admitidos
  • HNSW (32, 8 o 4 bits)
  • FLAT (32, 8 o 4 bits)
Funciones de distancia admitidas
  • CosineSimilarity
  • DotProductSimilarity
  • EuclideanDistance
  • MaxInnerProduct
Cláusulas de filtro admitidas
  • AnyTagEqualTo
  • EqualTo
Admite varios vectores en un registro
¿Se admite IsFilterable?
¿Se admite IsFullTextSearchable?
¿Se admite StoragePropertyName? No, use JsonSerializerOptions y JsonPropertyNameAttribute en su lugar. Consulta aquí para obtener más información.

Empezar

Para ejecutar Elasticsearch localmente para el desarrollo local o las pruebas, ejecute el script start-local con un comando:

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

Agregue el paquete NuGet del conector Elasticsearch Vector Store a su proyecto.

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

Puede agregar el almacén de vectores al contenedor de inserción de dependencias disponible en el KernelBuilder o al contenedor de inserción de dependencias IServiceCollection mediante métodos de extensión proporcionados por el 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")));

También se proporcionan métodos de extensión que no toman parámetros. Estos requieren que una instancia de la clase Elastic.Clients.Elasticsearch.ElasticsearchClient se registre por separado con el contenedor de inserción de dependencias.

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

Puede construir una instancia de Elasticsearch Vector Store directamente.

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

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

Es posible construir una referencia directa a una colección con nombre.

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

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

Asignación de datos

El conector de Elasticsearch usará System.Text.Json.JsonSerializer para mapear. Dado que Elasticsearch almacena documentos con una clave/identificador y un valor independientes, el asignador serializará todas las propiedades excepto la clave en un objeto JSON y la usará como valor.

Se admite el uso del JsonPropertyNameAttribute si se requiere un nombre de almacenamiento diferente al nombre de la propiedad del modelo de datos. También es posible usar una instancia de JsonSerializerOptions personalizada con una directiva de nomenclatura de propiedades personalizada. Para habilitar esto, se debe configurar un serializador de origen personalizado.

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, la función lambda de DefaultFieldNameInferrer se puede configurar para lograr el mismo resultado o para personalizar aún más la nomenclatura de propiedades en función de las condiciones 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");

Dado que se eligió una directiva de nomenclatura en mayúsculas con guiones bajos, este es un ejemplo de cómo se establecerá este tipo de dato en Elasticsearch. Tenga en cuenta también el uso de JsonPropertyNameAttribute en la propiedad Description para personalizar aún más la nomenclatura del almacenamiento.

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

No es compatible

No se admite.

No está soportado

No se admite.