Freigeben über


Definieren des Datenmodells

Microsoft.Extensions.VectorData verwendet einen Modell-ersten Ansatz für die Interaktion mit Datenbanken.

Alle Methoden zum Upsertieren oder Abrufen von Datensätzen verwenden stark typierte Modellklassen. Es gibt zwei Möglichkeiten zum Definieren des Datenmodells:

  • Indem Sie Eigenschaften für die Modellklassen mit Attributen versehen, die den Zweck jeder Eigenschaft angeben.
  • Indem Sie Ihr Speicherschema mithilfe einer Datensatzdefinition definieren, die Sie separat vom Datenmodell bereitstellen. Die Datensatzdefinition ist eine VectorStoreCollectionDefinition Eigenschaft, die Eigenschaften enthält.

Hier ist ein Beispiel für eine Klasse oder ein Datenmodell, dessen Eigenschaften mit VectorStore*Attribute Attributen versehen sind.

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

    [VectorStoreData(IsIndexed = true)]
    public required string HotelName { get; set; }

    [VectorStoreData(IsFullTextIndexed = true)]
    public required string Description { get; set; }

    [VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }

    [VectorStoreData(IsIndexed = true)]
    public required string[] Tags { get; set; }
}

Datenmodelleigenschaftenattribute

Die VectorStore*Attribute Attribute, die Datenmodelle für Vektordatenbanken definieren, sind:

VectorStoreKeyAttribute

Verwenden Sie das VectorStoreKeyAttribute Attribut, um anzugeben, dass Ihre Eigenschaft der Primärschlüssel des Datensatzes ist.

[VectorStoreKey]
public ulong HotelId { get; set; }

Die folgende Tabelle zeigt die Parameter für VectorStoreKeyAttribute.

Parameter Erforderlich Beschreibung
StorageName No Kann verwendet werden, um einen alternativen Namen für die Eigenschaft in der Datenbank anzugeben. Dieser Parameter wird nicht von allen Anbietern unterstützt, z. B. wenn Alternativen wie JsonPropertyNameAttribute unterstützt werden.

VectorStoreDataAttribute

Verwenden Sie das VectorStoreDataAttribute Attribut, um anzugeben, dass Ihre Eigenschaft allgemeine Daten enthält, bei denen es sich nicht um einen Schlüssel oder einen Vektor handelt.

[VectorStoreData(IsIndexed = true)]
public required string HotelName { get; set; }

Die folgende Tabelle zeigt die Parameter für VectorStoreDataAttribute.

Parameter Erforderlich Beschreibung
IsIndexed No Gibt an, ob die Eigenschaft für die Filterung indiziert werden soll, wenn eine Datenbank die Indizierung pro Eigenschaft erfordert. Der Standardwert lautet false.
IsFullTextIndexed No Gibt an, ob die Eigenschaft für die Volltextsuche für Datenbanken indiziert werden soll, die die Volltextsuche unterstützen. Der Standardwert lautet false.
StorageName No Kann verwendet werden, um einen alternativen Namen für die Eigenschaft in der Datenbank anzugeben. Dieser Parameter wird nicht von allen Anbietern unterstützt, z. B. wenn Alternativen wie JsonPropertyNameAttribute unterstützt werden.

VectorStoreVectorAttribute

Verwenden Sie das VectorStoreVectorAttribute Attribut, um anzugeben, dass Ihre Eigenschaft einen Vektor enthält.

[VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }

Es ist auch möglich, für Eigenschaften zu verwenden VectorStoreVectorAttribute , die keinen Vektortyp aufweisen, z. B. eine Eigenschaft vom Typ string. Wenn eine Eigenschaft auf diese Weise versehen ist, müssen Sie dem Vektorspeicher eine IEmbeddingGenerator Instanz bereitstellen. Beim Upserting des Datensatzes wird der Text in der string Eigenschaft automatisch konvertiert und als Vektor in der Datenbank gespeichert. (Es ist nicht möglich, einen Vektor mit diesem Mechanismus abzurufen.)

[VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
public string DescriptionEmbedding { get; set; }

Tipp

Weitere Informationen zur Verwendung der integrierten Einbettungsgenerierung finden Sie unter Let the vector store generate embeddings.

Die folgende Tabelle zeigt die Parameter für VectorStoreVectorAttribute.

Parameter Erforderlich Beschreibung
Dimensions Ja Die Anzahl der Dimensionen, die der Vektor hat. Dies ist beim Erstellen eines Vektorindexes für eine Auflistung erforderlich.
IndexKind No Der Indextyp, mit dem der Vektor indiziert werden soll. Der Standardwert variiert je nach Vektorspeichertyp.
DistanceFunction No Der Typ der Funktion, die beim Vektorvergleich während der Vektorsuche über diesen Vektor verwendet werden soll. Der Standardwert variiert je nach Vektorspeichertyp.
StorageName No Kann verwendet werden, um einen alternativen Namen für die Eigenschaft in der Datenbank anzugeben. Dieser Parameter wird nicht von allen Anbietern unterstützt, z. B. wenn Alternativen wie JsonPropertyNameAttribute unterstützt werden.

Allgemeine Indextypen und Abstandsfunktionstypen werden als statische Werte für die IndexKind Klassen und DistanceFunction Klassen bereitgestellt. Einzelne Vektorspeicherimplementierungen können auch eigene Indextypen und Entfernungsfunktionen verwenden, bei denen die Datenbank ungewöhnliche Typen unterstützt.

Datensatzdefinitionseigenschaften

Verwenden Sie die VectorStore*Property Klassen, um eine Datensatzdefinition zu erstellen, die Sie an das Datenmodell übergeben:

VectorStoreKeyProperty

Verwenden Sie die VectorStoreKeyProperty Klasse, um anzugeben, dass Ihre Eigenschaft der Schlüssel des Datensatzes ist.

new VectorStoreKeyProperty("HotelId", typeof(ulong)),

Die folgende Tabelle zeigt die Konfigurationseinstellungen für VectorStoreKeyProperty.

Parameter Erforderlich Beschreibung
Name Ja Der Name der Eigenschaft für das Datenmodell. Wird vom Mapper verwendet, um automatisch zwischen dem Speicherschema und dem Datenmodell und zum Erstellen von Indizes zuzuordnen.
Type No Der Typ der Eigenschaft für das Datenmodell. Wird vom Mapper verwendet, um automatisch zwischen dem Speicherschema und dem Datenmodell und zum Erstellen von Indizes zuzuordnen.
StorageName No Kann verwendet werden, um einen alternativen Namen für die Eigenschaft in der Datenbank anzugeben. Dieser Parameter wird nicht von allen Anbietern unterstützt, z. B. wenn Alternativen wie JsonPropertyNameAttribute unterstützt werden.

VectorStoreDataProperty

Verwenden Sie die VectorStoreDataProperty Klasse, um anzugeben, dass Ihre Eigenschaft allgemeine Daten enthält, die kein Schlüssel oder ein Vektor sind.

new VectorStoreDataProperty("HotelName", typeof(string)) { IsIndexed = true },
new VectorStoreDataProperty("Description", typeof(string)) { IsFullTextIndexed = true },

Die folgende Tabelle zeigt die Konfigurationseinstellungen für VectorStoreDataProperty.

Parameter Erforderlich Beschreibung
Name Ja Der Name der Eigenschaft für das Datenmodell. Wird vom Mapper verwendet, um automatisch zwischen dem Speicherschema und dem Datenmodell und zum Erstellen von Indizes zuzuordnen.
Type No Der Typ der Eigenschaft für das Datenmodell. Wird vom Mapper verwendet, um automatisch zwischen dem Speicherschema und dem Datenmodell und zum Erstellen von Indizes zuzuordnen.
IsIndexed No Gibt an, ob die Eigenschaft für die Filterung indiziert werden soll, wenn eine Datenbank die Indizierung pro Eigenschaft erfordert. Der Standardwert ist "false".
IsFullTextIndexed No Gibt an, ob die Eigenschaft für die Volltextsuche für Datenbanken indiziert werden soll, die die Volltextsuche unterstützen. Der Standardwert ist "false".
StorageName No Kann verwendet werden, um einen alternativen Namen für die Eigenschaft in der Datenbank anzugeben. Dieser Parameter wird nicht von allen Anbietern unterstützt, z. B. wenn Alternativen wie JsonPropertyNameAttribute unterstützt werden.

VectorStoreVectorProperty

Verwenden Sie die VectorStoreVectorProperty Klasse, um anzugeben, dass Ihre Eigenschaft einen Vektor enthält.

new VectorStoreVectorProperty("DescriptionEmbedding", typeof(float), dimensions: 4)

Die folgende Tabelle zeigt die Konfigurationseinstellungen für VectorStoreVectorProperty.

Parameter Erforderlich Beschreibung
Name Ja Der Name der Eigenschaft für das Datenmodell. Wird vom Mapper verwendet, um automatisch zwischen dem Speicherschema und dem Datenmodell und zum Erstellen von Indizes zuzuordnen.
Type No Der Typ der Eigenschaft für das Datenmodell. Wird vom Mapper verwendet, um automatisch zwischen dem Speicherschema und dem Datenmodell und zum Erstellen von Indizes zuzuordnen.
Dimensions Ja Die Anzahl der Dimensionen, die der Vektor hat. Dies ist erforderlich, um einen Vektorindex für eine Auflistung zu erstellen.
IndexKind No Der Indextyp, mit dem der Vektor indiziert werden soll. Der Standardwert variiert je nach Vektorspeichertyp.
DistanceFunction No Der Typ der Funktion, die beim Vektorvergleich während der Vektorsuche über diesen Vektor verwendet werden soll. Der Standardwert variiert je nach Vektorspeichertyp.
StorageName No Kann verwendet werden, um einen alternativen Namen für die Eigenschaft in der Datenbank anzugeben. Dieser Parameter wird nicht von allen Anbietern unterstützt, z. B. wenn Alternativen wie JsonPropertyNameAttribute unterstützt werden.
EmbeddingGenerator No Ermöglicht das Angeben einer Microsoft.Extensions.AI.IEmbeddingGenerator Instanz, die zum Generieren von Einbettungen automatisch für die versehene Eigenschaft verwendet werden soll.

Verwenden von Vektorspeicherabstraktionen ohne Definieren eines Datenmodells

Es gibt Fälle, in denen es nicht wünschenswert oder möglich ist, Ihr eigenes Datenmodell zu definieren. Stellen Sie sich z. B. vor, dass Sie zur Kompilierungszeit nicht wissen, wie Ihr Datenbankschema aussieht, und das Schema wird nur über die Konfiguration bereitgestellt. Das Erstellen eines Datenmodells, das das Schema widerspiegelt, wäre in diesem Fall unmöglich. Stattdessen können Sie die Zuordnung dynamisch mithilfe eines Dictionary<string, object?> Datensatztyps durchführen. Eigenschaften werden dem Dictionary Schlüssel als Eigenschaftenname und dem Wert als Eigenschaftswert hinzugefügt.

Hinweis

Die meisten Apps verwenden einfach stark typierte .NET-Typen, um ihre Daten zu modellieren. Dynamische Zuordnung erfolgt über Dictionary<string, object?> erweiterte, willkürliche Datenzuordnungsszenarien.

Bereitstellen von Schemainformationen bei Verwendung Dictionary

Bei Verwendung eines DictionaryDatenbankschemas müssen Anbieter immer noch wissen, wie das Datenbankschema aussieht. Ohne die Schemainformationen wäre der Anbieter nicht in der Lage, eine Sammlung zu erstellen oder zu der Speicherdarstellung zuzuordnen, die jede Datenbank verwendet.

Sie können eine Datensatzdefinition verwenden, um die Schemainformationen bereitzustellen. Im Gegensatz zu einem Datenmodell kann eine Datensatzdefinition zur Laufzeit aus der Konfiguration erstellt werden, wenn Schemainformationen zur Kompilierungszeit nicht bekannt sind.

Beispiel

Wenn Sie mit einem Anbieter arbeiten möchten Dictionary , geben Sie sie beim Erstellen der Sammlung als Datenmodell an. Stellen Sie außerdem eine Datensatzdefinition bereit.

VectorStoreCollectionDefinition definition = new()
{
    Properties =
    [
        new VectorStoreKeyProperty("Key", typeof(string)),
        new VectorStoreDataProperty("Term", typeof(string)),
        new VectorStoreDataProperty("Definition", typeof(string)),
        new VectorStoreVectorProperty("DefinitionEmbedding", typeof(ReadOnlyMemory<float>), dimensions: 1536)
    ]
};

// Use GetDynamicCollection instead of the regular GetCollection method
// to get an instance of a collection using Dictionary<string, object?>.
VectorStoreCollection<object, Dictionary<string, object?>> dynamicDataModelCollection =
    vectorStore.GetDynamicCollection("glossary", definition);

// Since schema information is available from the record definition,
// it's possible to create a collection with the right vectors,
// dimensions, indexes, and distance functions.
await dynamicDataModelCollection.EnsureCollectionExistsAsync();

// When retrieving a record from the collection,
// access key, data, and vector values via the dictionary entries.
Dictionary<string, object?>? record = await dynamicDataModelCollection.GetAsync("SK");
Console.WriteLine(record["Definition"]);