Utilisation du connecteur Elasticsearch (préversion)
Avertissement
La fonctionnalité de magasin de vecteurs du noyau sémantique est en version préliminaire, et des améliorations nécessitant des changements incompatibles peuvent encore survenir dans des circonstances limitées avant la version finale.
Aperçu
Le connecteur Elasticsearch Vector Store peut être utilisé pour accéder aux données et les gérer dans Elasticsearch. Le connecteur présente les caractéristiques suivantes.
Zone de fonctionnalité | Soutien |
---|---|
Les cartes de collection correspondent à | Index d'Elasticsearch |
Types de propriétés de clé pris en charge | corde |
Types de propriétés de données pris en charge | Tous les types pris en charge par System.Text.Json (etiher intégré ou à l’aide d’un convertisseur personnalisé) |
Types de propriétés vectorielles pris en charge |
|
Types d’index pris en charge |
|
Fonctions de distance prises en charge |
|
Clauses de filtre prises en charge |
|
Prend en charge plusieurs vecteurs dans un enregistrement | Oui |
La fonction IsFilterable est-elle prise en charge ? | Oui |
La fonctionnalité de recherche en texte intégral est-elle prise en charge ? | Oui |
NomDePropriétéDeStockage pris en charge ? | Non, utilisez JsonSerializerOptions et JsonPropertyNameAttribute à la place.
Voir ici pour plus d’informations. |
Commencer
Pour exécuter Elasticsearch localement pour le développement local ou les tests, exécutez le script start-local
avec une commande :
curl -fsSL https://elastic.co/start-local | sh
Ajoutez le package NuGet du connecteur Elasticsearch Vector Store à votre projet.
dotnet add package Elastic.SemanticKernel.Connectors.Elasticsearch --prerelease
Vous pouvez ajouter le magasin de vecteurs au conteneur d’injection de dépendances disponible sur le KernelBuilder
ou au conteneur d’injection de dépendances IServiceCollection
à l’aide de méthodes d’extension fournies par le noyau sémantique.
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")));
Les méthodes d’extension qui ne prennent aucun paramètre sont également fournies. Celles-ci nécessitent qu’une instance de la classe Elastic.Clients.Elasticsearch.ElasticsearchClient
soit inscrite séparément auprès du conteneur d’injection de dépendances.
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();
Vous pouvez construire directement une instance 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"))));
Il est possible de construire une référence directe à une collection nommée.
using Elastic.SemanticKernel.Connectors.Elasticsearch;
using Elastic.Clients.Elasticsearch;
var collection = new ElasticsearchVectorStoreRecordCollection<Hotel>(
new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("http://localhost:9200"))),
"skhotels");
Mappage des données
Le connecteur Elasticsearch utilise System.Text.Json.JsonSerializer
pour effectuer le mappage.
Dans la mesure où Elasticsearch stocke des documents avec une clé/id et une valeur distinctes, le mappeur sérialise toutes les propriétés à l’exception de la clé vers un objet JSON et l’utilise comme valeur.
L’utilisation du JsonPropertyNameAttribute
est prise en charge si un nom de stockage différent du nom de propriété du modèle de données est requis. Il est également possible d’utiliser une instance de JsonSerializerOptions
personnalisée avec une politique de nommage des propriétés personnalisée. Pour l’activer, un sérialiseur source personnalisé doit être configuré.
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");
En guise d’alternative, la fonction lambda DefaultFieldNameInferrer
peut être configurée pour obtenir le même résultat ou encore personnaliser davantage le nommage de propriété en fonction de conditions dynamiques.
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");
Étant donné qu'une politique de nommage en majuscules snake_case a été choisie, voici un exemple de la façon dont ce type de données sera défini dans Elasticsearch.
Notez également l’utilisation de JsonPropertyNameAttribute
sur la propriété Description
pour personnaliser davantage la nomenclature du stockage.
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
]
}
}
Non pris en charge
Non pris en charge.
Non pris en charge
Non pris en charge.