Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Microsoft.Extensions.VectorData Bibliothek bietet Vektorsuchfunktionen als Teil der Vektorspeicherabstraktionen. Zu diesen Funktionen gehören Filterung und viele weitere Optionen.
Tipp
Wenn Sie sehen möchten, wie Sie suchen können, ohne Einbettungen selbst zu generieren, lesen Sie , Lassen Sie den Vektorspeicher Einbettungen generieren.
Vektorsuche
Die SearchAsync Methode ermöglicht das Durchsuchen von Daten, die bereits vektorisiert wurden. Diese Methode verwendet einen Vektor und eine optionale VectorSearchOptions<TRecord> Klasse als Eingabe. SearchAsync ist für die folgenden Typen verfügbar:
Beachten Sie, dass VectorStoreCollection<TKey,TRecord>IVectorSearchable<TRecord> implementiert.
Wenn Sie über eine Sammlung verfügen, die bereits Daten enthält, können Sie sie ganz einfach durchsuchen. Hier ist ein Beispiel für die Verwendung von Qdrant.
public async Task SearchAsync()
{
// Create a Qdrant VectorStore object and choose
// an existing collection that already contains records.
VectorStore vectorStore = new QdrantVectorStore(new QdrantClient("localhost"), ownsClient: true);
VectorStoreCollection<ulong, Hotel> collection =
vectorStore.GetCollection<ulong, Hotel>("skhotels");
// Generate a vector for your search text, using
// your chosen embedding generation implementation.
ReadOnlyMemory<float> searchVector =
await GenerateAsync("I'm looking for a hotel where customer happiness is the priority.");
// Do the search, passing an options object with
// a Top value to limit results to the single top match.
IAsyncEnumerable<VectorSearchResult<Hotel>> searchResult =
collection.SearchAsync(searchVector, top: 1);
// Inspect the returned hotel.
await foreach (VectorSearchResult<Hotel> record in searchResult)
{
Console.WriteLine("Found hotel description: " + record.Record.Description);
Console.WriteLine("Found record score: " + record.Score);
}
}
Tipp
Weitere Informationen zum Generieren von Einbettungen finden Sie unter "Einbettungsgenerierung".
Suche mit automatisch generierten Einbettungen
Wenn Sie in Ihrem Vektorspeicher oder Ihrer Sammlung ein IEmbeddingGenerator<TInput,TEmbedding> konfiguriert haben, können Sie ein string direkt an SearchAsync übergeben, anstelle eines vorkomputierten Vektors. Der Vektorspeicher generiert automatisch die Sucheinbettung:
public async Task SearchWithAutoEmbeddingAsync()
{
// If an IEmbeddingGenerator is configured on the vector store or collection,
// you can pass a string directly to SearchAsync. The store generates
// the search embedding for you.
VectorStore vectorStore = new QdrantVectorStore(new QdrantClient("localhost"), ownsClient: true);
VectorStoreCollection<ulong, Hotel> collection =
vectorStore.GetCollection<ulong, Hotel>("skhotels");
// Pass the search text directly — no manual embedding generation required.
IAsyncEnumerable<VectorSearchResult<Hotel>> searchResult =
collection.SearchAsync("I'm looking for a hotel where customer happiness is the priority.", top: 1);
await foreach (VectorSearchResult<Hotel> record in searchResult)
{
Console.WriteLine("Found hotel description: " + record.Record.Description);
Console.WriteLine("Found record score: " + record.Score);
}
}
Informationen zum Konfigurieren eines Einbettungsgenerators in Ihrem Vektorspeicher finden Sie unter Let the vector store generate embeddings.
Unterstützte Vektortypen
SearchAsync verwendet einen generischen Typ als Vektorparameter. Die von den einzelnen Datenspeichern unterstützten Vektortypen variieren.
Es ist auch wichtig, dass der Suchvektortyp dem Zielvektor entspricht, der durchsucht wird, z. B. wenn Sie zwei Vektoren auf demselben Datensatz mit verschiedenen Vektortypen haben, stellen Sie sicher, dass der von Ihnen eingegebene Suchvektor mit dem Typ des zielspezifischen Vektors übereinstimmt. Informationen zum Auswählen eines Zielvektors, wenn Sie mehr als einen Vektor pro Datensatz haben, finden Sie unter VectorProperty.
Vektorsuchoptionen
Die folgenden Optionen können mithilfe der VectorSearchOptions<TRecord> Klasse bereitgestellt werden.
VectorProperty
Verwenden Sie die VectorProperty Option, um die Vektoreigenschaft anzugeben, die während der Suche als Ziel verwendet werden soll. Wenn keine angegeben wird und das Datenmodell nur einen Vektor enthält, wird dieser Vektor verwendet. Wenn das Datenmodell keinen Vektor oder mehrere Vektoren enthält und VectorProperty nicht angegeben wird, löst die Suchmethode eine Ausnahme aus.
public async Task VectorPropertySearch()
{
var vectorStore = new InMemoryVectorStore();
InMemoryCollection<int, Product> collection =
vectorStore.GetCollection<int, Product>("skproducts");
// Create the vector search options and indicate that you want to search the FeatureListEmbedding property.
var vectorSearchOptions = new VectorSearchOptions<Product>
{
VectorProperty = r => r.FeatureListEmbedding
};
// This snippet assumes searchVector is already provided, having been created using the embedding model of your choice.
IAsyncEnumerable<VectorSearchResult<Product>> searchResult =
collection.SearchAsync(searchVector, top: 3, vectorSearchOptions);
}
public sealed class Product
{
[VectorStoreKey]
public int Key { get; set; }
[VectorStoreData]
public required string Description { get; set; }
[VectorStoreData]
public required List<string> FeatureList { get; set; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> DescriptionEmbedding { get; set; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> FeatureListEmbedding { get; set; }
}
Ergebnisse überspringen oder top ergebnisse auswählen
Der top Parameter bei SearchAsync<TInput>(TInput, Int32, VectorSearchOptions<TRecord>, CancellationToken) und die VectorSearchOptions<TRecord>.Skip Option ermöglichen es Ihnen, die Anzahl der Ergebnisse einzuschränken. Der top Parameter beschränkt die Ergebnisse auf die obersten n Ergebnisse. Die Skip Option überspringt eine Anzahl von Ergebnissen vom Anfang des Ergebnis-Sets. Sie können diese Steuerelemente verwenden, um paging durchzuführen, wenn Sie eine große Anzahl von Ergebnissen mithilfe separater Aufrufe abrufen möchten.
// Create the vector search options and indicate
// that you want to skip the first 40 results.
VectorSearchOptions<Product> vectorSearchOptions = new()
{
Skip = 40
};
// This snippet assumes searchVector is already provided,
// having been created using the embedding model of your choice.
// Pass 'top: 20' to indicate that you want to retrieve
// the next 20 results after skipping the first 40.
IAsyncEnumerable<VectorSearchResult<Product>> searchResult =
collection.SearchAsync(searchVector, top: 20, vectorSearchOptions);
// Iterate over the search results.
await foreach (VectorSearchResult<Product> result in searchResult)
{
Console.WriteLine(result.Record.FeatureList);
}
Der Standardwert für Skip ist 0.
IncludeVectors
Mit der VectorSearchOptions<TRecord>.IncludeVectors Option können Sie angeben, ob Vektoren in den Suchergebnissen zurückgegeben werden sollen. Wenn false, dann bleiben die Vektoreigenschaften für das zurückgegebene Modell null. Die Verwendung false kann die Menge der daten, die während der Suche aus dem Vektorspeicher abgerufen werden, erheblich reduzieren und so die Suchvorgänge effizienter gestalten.
Der Standardwert für IncludeVectors ist false.
// Create the vector search options and indicate that you want to include vectors in the search results.
var vectorSearchOptions = new VectorSearchOptions<Product>
{
IncludeVectors = true
};
// This snippet assumes searchVector is already provided,
// having been created using the embedding model of your choice.
IAsyncEnumerable<VectorSearchResult<Product>> searchResult =
collection.SearchAsync(searchVector, top: 3, vectorSearchOptions);
// Iterate over the search results.
await foreach (VectorSearchResult<Product> result in searchResult)
{
Console.WriteLine(result.Record.FeatureList);
}
Filter
Verwenden Sie die VectorSearchOptions<TRecord>.Filter Option, um die Datensätze in der ausgewählten Auflistung zu filtern, bevor Sie die Vektorsuche anwenden. Dies hat mehrere Vorteile:
- Verringert latenz- und Verarbeitungskosten, da nur Datensätze, die nach dem Filtern verbleiben, mit dem Suchvektor verglichen werden müssen und daher weniger Vektorvergleiche durchgeführt werden müssen.
- Schränkt das Resultset ein. Sie können z. B. die Zugriffssteuerung implementieren, indem Sie Daten ausschließen, auf die der Benutzer keinen Zugriff haben soll.
Damit Felder zum Filtern verwendet werden können, müssen sie zuerst indiziert werden. Einige Vektorspeicher ermöglichen das Filtern mithilfe eines beliebigen Felds, könnten aber möglicherweise optional die Indizierung erlauben, um die Filterleistung zu verbessern.
Wenn Sie eine Sammlung über die Vektorspeicherabstraktionen erstellen und die Filterung für ein Feld aktivieren möchten, legen Sie die IsIndexed Eigenschaft beim Definieren des Datenmodells oder beim Erstellen der Datensatzdefinition auf true die Eigenschaft fest.
Tipp
Weitere Informationen zum Aktivieren IsIndexedfinden Sie unter VectorStoreDataAttribute oder VectorStoreDataProperty.
Filter werden mithilfe von LINQ-Ausdrücken basierend auf dem Typ des Datenmodells ausgedrückt. Der unterstützte LINQ-Ausdruckssatz variiert je nach der funktionalität, die von jeder Datenbank unterstützt wird, aber alle Datenbanken unterstützen eine breite Basis allgemeiner Ausdrücke, z. B. gleich, ungleich, andund or.
public static async Task FilteredSearchAsync()
{
// Create the vector search options and set the filter on the options.
VectorSearchOptions<Glossary> vectorSearchOptions = new()
{
Filter = r => r.Category == "External Definitions" && r.Tags.Contains("memory")
};
// This snippet assumes searchVector is already provided,
// having been created using the embedding model of your choice.
IAsyncEnumerable<VectorSearchResult<Glossary>> searchResult =
collection.SearchAsync(searchVector, top: 3, vectorSearchOptions);
// Iterate over the search results.
await foreach (VectorSearchResult<Glossary> result in searchResult)
{
Console.WriteLine(result.Record.Definition);
}
}
sealed class Glossary
{
[VectorStoreKey]
public ulong Key { get; set; }
// Category is marked as indexed, since you want to filter using this property.
[VectorStoreData(IsIndexed = true)]
public required string Category { get; set; }
// Tags is marked as indexed, since you want to filter using this property.
[VectorStoreData(IsIndexed = true)]
public required List<string> Tags { get; set; }
[VectorStoreData]
public required string Term { get; set; }
[VectorStoreData]
public required string Definition { get; set; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> DefinitionEmbedding { get; set; }
}