Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
La bibliothèque Microsoft.Extensions.VectorData fournit des fonctionnalités de recherche vectorielle dans le cadre de ses abstractions de magasin de vecteurs. Ces fonctionnalités incluent le filtrage et de nombreuses autres options.
Recherche vectorielle
La SearchAsync méthode effectue une recherche de similarité, retournant des enregistrements dont la propriété vectorielle est la plus similaire à une valeur donnée. En supposant que vous disposez d’une collection qui contient déjà des données, voici un exemple minimal montrant la recherche vectorielle à l’aide de Qdrant :
// Create a Qdrant VectorStore object and get a VectorStoreCollection for a collection that already contains records
VectorStore vectorStore = new QdrantVectorStore(new QdrantClient("localhost"), ownsClient: true);
VectorStoreCollection<ulong, Hotel> collection = vectorStore.GetCollection<ulong, Hotel>("skhotels");
// Get the 3 hotels whose vector property is most similar to the query text
IAsyncEnumerable<VectorSearchResult<Hotel>> results = collection.SearchAsync("Big rooms with a view", top: 3);
// Inspect the returned hotels and their similarity scores
await foreach (VectorSearchResult<Hotel> record in results)
{
Console.WriteLine("Found hotel description: " + record.Record.Description);
Console.WriteLine("Found record score: " + record.Score);
}
Pour plus d’informations sur la génération d’embeddings, consultez Propriétés des vecteurs et génération d’embeddings.
Nombre de résultats et saut des résultats
SearchAsync a un paramètre obligatoire top qui contrôle le nombre maximal d’enregistrements retournés par la recherche. Considérez toujours combien de meilleurs enregistrements vous avez réellement besoin, car une récupération excessive peut réduire les performances de l'application.
IAsyncEnumerable<VectorSearchResult<Hotel>> searchResult = collection.SearchAsync("Big rooms with a view", top: 3);
En outre, vous pouvez, si vous le souhaitez, ignorer les enregistrements. Par exemple, la recherche suivante retourne les 20 produits les plus pertinents après avoir ignoré 40 :
IAsyncEnumerable<VectorSearchResult<Product>> results = collection.SearchAsync(
"Green socks",
top: 20,
new() { Skip = 40 });
top et Skip peuvent être utilisés pour procéder à la pagination afin d'obtenir un grand nombre de résultats au moyen d'appels distincts. Toutefois, cette technique peut ne pas fonctionner correctement sur votre base de données, car elle doit toujours rechercher et traiter les enregistrements ignorés. Pour plus d’informations, consultez la documentation de votre base de données.
Filtrage des métadonnées
Utilisez l’option VectorSearchOptions<TRecord>.Filter pour filtrer les enregistrements de la collection choisie avant d’appliquer la recherche vectorielle. Cela présente plusieurs avantages :
- Réduit la latence et le coût de traitement, car seuls les enregistrements restants après le filtrage doivent être comparés au vecteur de recherche et, par conséquent, moins de comparaisons de vecteurs doivent être effectuées.
- Limite le jeu de résultats. Par exemple, vous pouvez implémenter le contrôle d’accès en excluant les données auxquelles l’utilisateur ne doit pas avoir accès ou effectuer une recherche uniquement dans une catégorie spécifique de produits.
Pour que les champs soient utilisés pour le filtrage, de nombreux magasins vectoriels nécessitent que ces champs soient indexés en premier. Pour plus d’informations sur l’activation de l’indexation sur les propriétés de données, consultez Propriété de données.
Les filtres sont exprimés à l’aide d’expressions LINQ basées sur le type du modèle de données. L’ensemble d’expressions LINQ prises en charge varie en fonction des fonctionnalités prises en charge par chaque base de données, mais toutes les bases de données prennent en charge une large base d’expressions communes, par exemple, égales, non égales, andet or.
class Glossary
{
// ...
// 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; }
}
IAsyncEnumerable<VectorSearchResult<Glossary>> results = collection.SearchAsync(
"Some term",
top: 3,
new()
{
Filter = r => r.Category == "External Definitions" && r.Tags.Contains("memory")
});
Inclure des vecteurs dans les résultats
Par défaut, les propriétés vectorielles ne sont pas incluses dans les résultats de la recherche, ce qui réduit le transfert de données. Vous pouvez configurer la recherche pour les inclure :
IAsyncEnumerable<VectorSearchResult<Product>> results = collection.SearchAsync(
"Green socks",
top: 3,
new() { IncludeVectors = true });
Spécifier la propriété vecteur
Dans la plupart des scénarios, une seule propriété vectorielle est définie dans le modèle de données et SearchAsync recherche automatiquement sur celle-ci. Toutefois, lorsque plusieurs propriétés vectorielles sont définies, vous devez spécifier celle qui doit être utilisée :
class Product
{
// ...
// Multiple vector properties:
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> DescriptionEmbedding { get; set; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> FeatureListEmbedding { get; set; }
}
IAsyncEnumerable<VectorSearchResult<Hotel>> results = collection.SearchAsync(
"I'm looking for a product with a specific feature.",
top: 3,
new() { VectorProperty = r => r.FeatureListEmbedding });
Recherche hybride
La recherche hybride combine la recherche de similarité vectorielle avec la recherche par mot clé traditionnelle, en exécutant à la fois en parallèle et en retournant une combinaison des deux jeux de résultats. Cela peut améliorer la qualité de la recherche, car la correspondance de mots clés peut capturer des correspondances exactes de termes que la similarité vectorielle peut manquer, et inversement.
Note
La recherche hybride est disponible uniquement sur les bases de données qui le prennent en charge. Seuls les fournisseurs de ces bases de données implémentent l’interface IKeywordHybridSearchable<TRecord> .
Pour utiliser la recherche hybride, votre modèle de données a besoin d’un champ de chaîne avec la recherche en texte intégral activée via IsFullTextIndexed:
class Hotel
{
[VectorStoreKey]
public ulong Key { get; set; }
[VectorStoreData(IsFullTextIndexed = true)]
public required string Description { get; set; }
[VectorStoreVector(1536)]
public string DescriptionEmbedding { get; set; }
}
Appelez ensuite HybridSearchAsync, en passant le texte de recherche et les mots-clés :
var hybridCollection = (IKeywordHybridSearchable<Hotel>)collection;
IAsyncEnumerable<VectorSearchResult<Hotel>> results = hybridCollection.HybridSearchAsync(
"I'm looking for a hotel where customer happiness is the priority.",
["happiness", "hotel", "customer"],
top: 3);
Toutes les options décrites pour la recherche vectorielle (top, Skip, Filter, IncludeVectors, VectorProperty) sont également disponibles pour la recherche hybride via HybridSearchOptions<TRecord>.
En outre, la recherche hybride prend en charge une AdditionalProperty option permettant de spécifier la propriété de recherche en texte intégral à cibler. Si votre modèle de données n’a qu’une seule propriété avec IsFullTextIndexed = truelaquelle elle est utilisée automatiquement ; s’il existe plusieurs, vous devez spécifier celle-ci :
IAsyncEnumerable<VectorSearchResult<Hotel>> results = hybridCollection.HybridSearchAsync(
"I'm looking for a hotel where customer happiness is the priority.",
["happiness", "hotel", "customer"],
top: 3,
new()
{
VectorProperty = r => r.DescriptionEmbedding,
AdditionalProperty = r => r.Description
});