Vectorzoekopdrachten met vectoropslagproviders

De bibliotheek Microsoft.Extensions.VectorData biedt vectorzoekmogelijkheden als onderdeel van de abstracties van het vectorarchief. Deze mogelijkheden omvatten filteren en vele andere opties.

De SearchAsync methode voert een overeenkomstenzoekopdracht uit, waarbij records worden geretourneerd waarvan de vectoreigenschap het meest lijkt op een bepaalde waarde. Ervan uitgaande dat u een verzameling hebt die al gegevens bevat, is dit een minimaal voorbeeld met vectorzoekopdrachten met 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);
}

Zie Vector-eigenschappen en het genereren van inbedding voor meer informatie over het genereren van inbedding.

Aantal resultaten en overslaan van resultaten

SearchAsync heeft een verplichte top parameter waarmee het maximale aantal records dat door de zoekopdracht wordt geretourneerd, wordt bepaald. Houd altijd rekening met het aantal toprecords dat u daadwerkelijk nodig hebt, omdat overfetching de prestaties van toepassingen kan verminderen:

IAsyncEnumerable<VectorSearchResult<Hotel>> searchResult = collection.SearchAsync("Big rooms with a view", top: 3);

Daarnaast kunt u desgewenst records overslaan. De volgende zoekopdracht retourneert bijvoorbeeld de 20 meest relevante producten na het overslaan van 40:

IAsyncEnumerable<VectorSearchResult<Product>> results = collection.SearchAsync(
    "Green socks",
    top: 20,
    new() { Skip = 40 });

top en Skip kan worden gebruikt om paging uit te voeren om een groot aantal resultaten op te halen met behulp van afzonderlijke aanroepen. Deze techniek werkt echter mogelijk niet goed in uw database, omdat de overgeslagen records nog steeds moeten worden gevonden en verwerkt. Raadpleeg uw databasedocumentatie voor meer informatie.

Metagegevens filteren

Gebruik de VectorSearchOptions<TRecord>.Filter optie om de records in de gekozen verzameling te filteren voordat u de vectorzoekopdracht toepast. Dit heeft meerdere voordelen:

  • Vermindert de latentie en verwerkingskosten, omdat alleen records die na het filteren resteren, moeten worden vergeleken met de zoekvector en daarom moeten er minder vectorvergelijkingen worden uitgevoerd.
  • Hiermee beperkt u de resultatenset. U kunt bijvoorbeeld toegangsbeheer implementeren door gegevens uit te sluiten waartoe de gebruiker geen toegang mag hebben of alleen binnen een specifieke categorie producten mag zoeken.

Voor velden die moeten worden gebruikt voor filteren, moeten deze velden eerst worden geïndexeerd in veel vectorarchieven. Zie de eigenschap Gegevens voor meer informatie over het inschakelen van indexering van gegevenseigenschappen.

Filters worden uitgedrukt met LINQ-expressies op basis van het type gegevensmodel. De set LINQ-expressies die worden ondersteund, is afhankelijk van de functionaliteit die door elke database wordt ondersteund, maar alle databases ondersteunen een brede basis van algemene expressies, bijvoorbeeld gelijk aan, niet gelijk aan, anden 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")
    });

Vectoren opnemen in resultaten

Vectoreigenschappen worden standaard niet opgenomen in de zoekresultaten, waardoor de gegevensoverdracht wordt verminderd. U kunt de zoekopdracht zo configureren dat deze worden opgenomen:

IAsyncEnumerable<VectorSearchResult<Product>> results = collection.SearchAsync(
    "Green socks",
    top: 3,
    new() { IncludeVectors = true });

De vectoreigenschap opgeven

In de meeste scenario's wordt slechts één vectoreigenschap gedefinieerd in het gegevensmodel en SearchAsync wordt er automatisch mee gezocht. Wanneer er echter meerdere vectoreigenschappen zijn gedefinieerd, moet u opgeven welke moet worden gebruikt:

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 });

Hybride zoekopdracht combineert vector-overeenkomsten met traditionele trefwoordzoekopdrachten, waarbij zowel parallel als een combinatie van de twee resultatensets wordt uitgevoerd. Dit kan de zoekkwaliteit verbeteren, omdat trefwoordkoppeling exacte termen kan vastleggen die vectorovereenkomsten kunnen missen en omgekeerd.

Opmerking

Hybride zoekopdrachten zijn alleen beschikbaar voor databases die deze ondersteunen. Alleen providers voor deze databases implementeren de IKeywordHybridSearchable<TRecord> interface.

Als u hybride zoekopdrachten wilt gebruiken, heeft uw gegevensmodel een tekenreeksveld nodig waarvoor zoeken in volledige tekst is ingeschakeld 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; }
}

HybridSearchAsyncRoep vervolgens aan, waarbij zowel zoektekst als trefwoorden worden doorgegeven:

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);

Alle opties die worden beschreven voor vectorzoekopdrachten (top, Skip, Filter, IncludeVectors) VectorPropertyzijn ook beschikbaar voor hybride zoeken via HybridSearchOptions<TRecord>.

Hybride zoekopdrachten ondersteunen bovendien een AdditionalProperty optie voor het opgeven van welke zoekeigenschap voor volledige tekst moet worden gebruikt. Als uw gegevensmodel slechts één eigenschap heeft met IsFullTextIndexed = true, wordt deze automatisch gebruikt; als er meerdere zijn, moet u opgeven welke u wilt gebruiken.

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
    });