Freigeben über


Verwenden des Redis-Connectors (Vorschau)

Warnung

Die Funktionalität des semantischen Kernelvektorspeichers befindet sich in der Vorschau, und Verbesserungen, die fehlerhafte Änderungen erfordern, können unter begrenzten Umständen noch vor der Veröffentlichung auftreten.

Übersicht

Der Redis Vector Store-Connector kann verwendet werden, um auf Daten in Redis zuzugreifen und sie zu verwalten. Der Connector unterstützt sowohl Hashes als auch JSON-Modi und welchen Modus Sie auswählen, um zu bestimmen, welche anderen Features unterstützt werden.

Der Verbinder weist die folgenden Merkmale auf.

Featurebereich Unterstützung
Auflistungszuordnungen Redis index with prefix set to <collectionname>:
Unterstützte Schlüsseleigenschaftentypen Zeichenfolge
Unterstützte Datentypen für Datentypen Bei Verwendung von Hashes:
  • Zeichenfolge
  • int
  • uint
  • long
  • ulong
  • double
  • float
  • bool
Bei Verwendung von JSON:
Alle Typen, die in JSON serialisierbar sind
Unterstützte Vektoreigenschaftentypen
  • ReadOnlyMemory<float>
  • ReadOnlyMemory<Double>
Unterstützte Indextypen
  • Hnsw
  • Flach
Unterstützte Entfernungsfunktionen
  • KosinusSimilarität
  • DotProductSimilarity
  • EuklideanDistance
Unterstützt mehrere Vektoren in einem Datensatz Ja
IstFilterbar unterstützt? Ja
WirdFullTextSearchable unterstützt? Ja
StoragePropertyName wird unterstützt? Bei Verwendung von Hashes: Ja
Verwenden Sie bei Verwendung von JSON: Nein, verwenden JsonSerializerOptions Sie sie stattdessen JsonPropertyNameAttribute . Weitere Informationen finden Sie hier.

Erste Schritte

Fügen Sie ihrem Projekt das Nuget-Paket des Redis Vector Store-Connectors hinzu.

dotnet add package Microsoft.SemanticKernel.Connectors.Redis --prerelease

Sie können den Vektorspeicher dem Container zum Einfügen von Abhängigkeiten hinzufügen, der für den KernelBuilder Container für Abhängigkeitseinfügungen verfügbar ist, oder dem IServiceCollection Container zum Einfügen von Abhängigkeiten mithilfe von Erweiterungsmethoden, die vom semantischen Kernel bereitgestellt werden.

using Microsoft.SemanticKernel;

// Using Kernel Builder.
var kernelBuilder = Kernel
    .CreateBuilder()
    .AddRedisVectorStore("localhost:6379");
using Microsoft.SemanticKernel;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRedisVectorStore("localhost:6379");

Erweiterungsmethoden, die keine Parameter verwenden, werden ebenfalls bereitgestellt. Dazu muss eine Instanz der Redis IDatabase separat beim Abhängigkeitseinfügungscontainer registriert werden.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using StackExchange.Redis;

// Using Kernel Builder.
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.Services.AddSingleton<IDatabase>(sp => ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());
kernelBuilder.AddRedisVectorStore();
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using StackExchange.Redis;

// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IDatabase>(sp => ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());
builder.Services.AddRedisVectorStore();

Sie können eine Redis Vector Store-Instanz direkt erstellen.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

var vectorStore = new RedisVectorStore(ConnectionMultiplexer.Connect("localhost:6379").GetDatabase());

Es ist möglich, einen direkten Verweis auf eine benannte Auflistung zu erstellen. Dabei müssen Sie zwischen der JSON- oder Hashes-Instanz wählen, je nachdem, wie Sie Daten in Redis speichern möchten.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

// Using Hashes.
var hashesCollection = new RedisHashSetVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelshashes");
using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

// Using JSON.
var jsonCollection = new RedisJsonVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelsjson");

Beim Erstellen oder Registrieren eines RedisVectorStore Containers für die Abhängigkeitseinfügung ist es möglich, eine RedisVectorStoreOptions Instanz zu übergeben, die den bevorzugten Verwendeten Speichertyp/-modus konfiguriert: Hashes oder JSON. Wenn nicht angegeben, ist der Standardwert JSON.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

var vectorStore = new RedisVectorStore(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    new() { StorageType = RedisStorageType.HashSet });

Erste Schritte

Installieren Sie den semantischen Kernel mit den Redis-Extras, die den Redis-Client enthalten.

pip install semantic-kernel[redis]

Anschließend können Sie eine Vektorspeicherinstanz mithilfe der RedisStore Klasse erstellen. Dadurch werden die Umgebungsvariablen REDIS_CONNECTION_STRING verwendet, um eine Verbindung mit einer Redis-Instanz herzustellen, diese Werte können auch direkt bereitgestellt werden.


from semantic_kernel.connectors.memory.redis import RedisStore

vector_store = RedisStore()

Sie können den Vektorspeicher auch mit Ihrer eigenen Instanz des Redis-Datenbankclients erstellen.

from redis.asyncio.client import Redis
from semantic_kernel.connectors.memory.redis import RedisStore

redis_database = Redis.from_url(url="https://<your-redis-service-name>")
vector_store = RedisStore(redis_database=redis_database)

Sie können eine Sammlung auch direkt erstellen, aber es gibt zwei Arten von Auflistungen, eine für Hashes und eine für JSON.

from semantic_kernel.connectors.memory.redis import RedisHashsetCollection, RedisJsonCollection

hash_collection = RedisHashsetCollection(collection_name="skhotels", data_model_type=Hotel)
json_collection = RedisJsonCollection(collection_name="skhotels", data_model_type=Hotel)

Beim Erstellen einer Sammlung aus dem Vektorspeicher können Sie den Sammlungstyp als Enumeration übergeben: RedisCollectionTypesDer Standardwert ist eine Hashauflistung.

from semantic_kernel.connectors.memory.redis import RedisStore, RedisCollectionTypes

vector_store = RedisStore()
collection = vector_store.get_collection(
    collection_name="skhotels", 
    data_model_type=Hotel, 
    collection_type=RedisCollectionTypes.JSON,
)

Serialisierung

Die Redis-Auflistungen verwenden beide ein Diktieren als Datenformat beim Upserting, aber die Struktur der Diktats unterscheidet sich zwischen ihnen.

Ein Beispiel für JSON-Sammlungen finden Sie in Redis-Dokumenten .

Für Hashset-Auflistungen wird der Befehl "hset" mit dem Schlüsselfeld als name, Datenfeldern als mapping -> metadata und Vektoren verwendet, wie mapping -> [vector_field_name] hier finden Sie weitere Informationen.

Weitere Informationen zu diesem Konzept finden Sie in der Serialisierungsdokumentation.

Erste Schritte

Fügen Sie die neueste Version des Semantischen Kernel-Redis-Datenconnectors in Ihr Maven-Projekt ein, indem Sie die folgende Abhängigkeit zu Ihrem pom.xmlHinzufügen hinzufügen:

<dependency>
    <groupId>com.microsoft.semantic-kernel</groupId>
    <artifactId>semantickernel-data-redis</artifactId>
    <version>[LATEST]</version>
</dependency>

Anschließend können Sie eine Vektorspeicherinstanz mithilfe der RedisVectorStore Klasse erstellen, wobei der Redis-Client (JedisPooled) als Parameter vorhanden ist.

import com.microsoft.semantickernel.data.redis.RedisJsonVectorStoreRecordCollectionOptions;
import com.microsoft.semantickernel.data.redis.RedisStorageType;
import com.microsoft.semantickernel.data.redis.RedisVectorStore;
import com.microsoft.semantickernel.data.redis.RedisVectorStoreOptions;
import redis.clients.jedis.JedisPooled;

public class Main {
    public static void main(String[] args) {
        JedisPooled jedis = new JedisPooled("<your-redis-url>");

        // Build a Redis Vector Store
        // Available storage types are JSON and HASHSET. Default is JSON.
        var vectorStore = RedisVectorStore.builder()
            .withClient(jedis)
            .withOptions(
                RedisVectorStoreOptions.builder()
                    .withStorageType(RedisStorageType.HASH_SET).build())
            .build();
    }
}

Sie können eine Sammlung auch direkt abrufen.

var collection = vectorStore.getCollection("skhotels",
    RedisJsonVectorStoreRecordCollectionOptions.<Hotel>builder()
        .withRecordClass(Hotel.class)
        .build());

Indexpräfixe

Redis verwendet ein System der Schlüsselpräfixierung, um einen Datensatz einem Index zuzuordnen. Beim Erstellen eines Indexes können Sie ein oder mehrere Präfixe angeben, die mit diesem Index verwendet werden sollen. Wenn Sie einen Datensatz diesem Index zuordnen möchten, müssen Sie dem Schlüssel dieses Datensatzes das Präfix hinzufügen.

Wenn Sie z. B. einen Index skhotelsjson erstellen, der mit einem Präfix von skhotelsjson:, wenn Sie einen Datensatz mit Schlüssel h1festlegen, muss der Datensatzschlüssel wie folgt skhotelsjson:h1 dem Index hinzugefügt werden.

Beim Erstellen einer neuen Auflistung mithilfe des Redis-Connectors erstellt der Connector einen Index in Redis mit einem Präfix, das aus dem Auflistungsnamen und einem Doppelpunkt besteht, wie hier <collectionname>:dargestellt. Standardmäßig präfixiert der Connector auch alle Schlüssel mit diesem Präfix, wenn Datensatzvorgänge wie "Get", "Upsert" und "Delete" durchgeführt werden.

Wenn Sie kein Präfix verwenden möchten, das aus dem Auflistungsnamen und einem Doppelpunkt besteht, ist es möglich, das Präfixverhalten zu deaktivieren und den vollständig präfixierten Schlüssel an die Datensatzvorgänge zu übergeben.

using Microsoft.SemanticKernel.Connectors.Redis;
using StackExchange.Redis;

var collection = new RedisJsonVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelsjson",
    new() { PrefixCollectionNameToKeyNames = false });

await collection.GetAsync("myprefix_h1");
from semantic_kernel.connectors.memory.redis import RedisJsonCollection

collection = RedisJsonCollection(collection_name="skhotels", data_model_type=hotel, prefix_collection_name_to_key_names=False)

await collection.get("myprefix_h1")
var collection = vectorStore.getCollection("skhotels",
    RedisJsonVectorStoreRecordCollectionOptions.<Hotel>builder()
        .withRecordClass(Hotel.class)
        .withPrefixCollectionName(false)
        .build());

collection.getAsync("myprefix_h1", null).block();

Datenzuordnung

Redis unterstützt zwei Modi zum Speichern von Daten: JSON und Hashes. Der Redis-Connector unterstützt beide Speichertypen, und die Zuordnung unterscheidet sich je nach ausgewähltem Speichertyp.

Datenzuordnung bei Verwendung des JSON-Speichertyps

Bei Verwendung des JSON-Speichertyps verwendet System.Text.Json.JsonSerializer der Redis-Connector die Zuordnung. Da Redis Datensätze mit einem separaten Schlüssel und Wert speichert, serialisiert der Mapper alle Eigenschaften mit Ausnahme des Schlüssels zu einem JSON-Objekt und verwendet diese als Wert.

Die Verwendung der JsonPropertyNameAttribute Eigenschaft wird unterstützt, wenn ein anderer Speichername für den Namen der Datenmodelleigenschaft erforderlich ist. Es ist auch möglich, eine benutzerdefinierte Instanz mit einer benutzerdefinierten JsonSerializerOptions Eigenschaftsbenennungsrichtlinie zu verwenden. Um dies zu ermöglichen, muss dies JsonSerializerOptions an den RedisJsonVectorStoreRecordCollection Bau übergeben werden.

var jsonSerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper };
var collection = new RedisJsonVectorStoreRecordCollection<Hotel>(
    ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
    "skhotelsjson",
    new() { JsonSerializerOptions = jsonSerializerOptions });

Da eine Benennungsrichtlinie für Schlangenbuchstaben ausgewählt wurde, finden Sie hier ein Beispiel dafür, wie dieser Datentyp in Redis festgelegt wird. Beachten Sie außerdem die Verwendung der JsonPropertyNameAttribute Description Eigenschaft, um die Speicherbenennung weiter anzupassen.

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

public class Hotel
{
    [VectorStoreRecordKey]
    public ulong 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.CosineDistance, IndexKind.Hnsw)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
}
JSON.SET skhotelsjson:h1 $ '{ "HOTEL_NAME": "Hotel Happy", "HOTEL_DESCRIPTION": "A place where everyone can be happy.", "DESCRIPTION_EMBEDDING": [0.9, 0.1, 0.1, 0.1] }'

Datenzuordnung bei Verwendung des Hashes-Speichertyps

Bei Verwendung des Hashes-Speichertyps stellt der Redis-Connector eine eigene Zuordnung zur Zuordnung bereit. Dieser Mapper zuordnen jede Eigenschaft zu einem Feldwertpaar, das vom Befehl Redis HSET unterstützt wird.

Für Dateneigenschaften und Vektoreigenschaften können Sie Feldnamen außer Kraft setzen, die im Speicher verwendet werden sollen, die sich von den Eigenschaftennamen im Datenmodell unterscheiden. Dies wird für Schlüssel nicht unterstützt, da Schlüssel nicht in Redis benannt werden können.

Eigenschaftsnamenüberschreibung erfolgt durch Festlegen der StoragePropertyName Option über die Datenmodellattribute oder Datensatzdefinition.

Nachfolgend sehen Sie ein Beispiel für ein Datenmodell, bei dem StoragePropertyName die Attribute festgelegt sind und wie diese in Redis festgelegt werden.

using Microsoft.Extensions.VectorData;

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

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

    [VectorStoreRecordData(IsFullTextSearchable = true, StoragePropertyName = "hotel_description")]
    public string Description { get; set; }

    [VectorStoreRecordVector(Dimensions: 4, DistanceFunction.CosineDistance, IndexKind.Hnsw, StoragePropertyName = "hotel_description_embedding")]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
}
HSET skhotelshashes:h1 hotel_name "Hotel Happy" hotel_description 'A place where everyone can be happy.' hotel_description_embedding <vector_bytes>