Filters in vectorquery's

U kunt een vectorfiltermodi instellen op een vectorquery om op te geven of u wilt filteren vóór of na de uitvoering van de query.

Filters bepalen het bereik van een vectorquery. Filters worden ingesteld en herhaald over niet-vectortekenreeksen en numerieke velden die zijn toegeschreven aan filterable de index, maar het doel van een filter bepaalt waar de vectorquery over wordt uitgevoerd: de volledige doorzoekbare ruimte of de inhoud van een zoekresultaat.

In dit artikel wordt elke filtermodus beschreven en wordt beschreven wanneer u deze kunt gebruiken.

Voorfiltermodus

Voorfiltering past filters toe voordat query's worden uitgevoerd, waardoor het zoekoppervlak wordt verkleind waar het vectorzoekalgoritmen naar vergelijkbare inhoud zoeken. In een vectorquery preFilter is dit de standaardwaarde.

Diagram of prefilters.

Postfiltermodus

Na filteren worden filters toegepast na het uitvoeren van query's, waardoor de zoekresultaten worden beperkt.

Diagram of post-filters.

Benchmarktests van vectorfiltermodi

Om inzicht te krijgen in de voorwaarden waaronder de ene filtermodus beter presteert dan de andere, hebben we een reeks tests uitgevoerd om queryresultaten te evalueren ten opzichte van kleine, middelgrote en grote indexen.

  • Klein (100.000 documenten, index van 2,5 GB, 1536 dimensies)
  • Gemiddeld (1 miljoen documenten, index van 25 GB, 1536 dimensies)
  • Groot (1 miljard documenten, index van 1,9 TB, 96 dimensies)

Voor de kleine en middelgrote workloads hebben we een Standard 2-service (S2) gebruikt met één partitie en één replica. Voor de grote workload hebben we een Standard 3-service (S3) gebruikt met 12 partities en één replica.

Indexen hadden een identieke constructie: één sleutelveld, één vectorveld, één tekstveld en één numeriek filterbaar veld. De volgende index wordt gedefinieerd met de syntaxis 2023-07-01-preview.

def get_index_schema(self, index_name, dimensions):
    return {
        "name": index_name,
        "fields": [
            {"name": "id", "type": "Edm.String", "key": True, "searchable": True},
            {"name": "content_vector", "type": "Collection(Edm.Single)", "dimensions": dimensions,
              "searchable": True, "retrievable": True, "filterable": False, "facetable": False, "sortable": False,
              "vectorSearchConfiguration": "defaulthnsw"},
            {"name": "text", "type": "Edm.String", "searchable": True, "filterable": False, "retrievable": True,
              "sortable": False, "facetable": False},
            {"name": "score", "type": "Edm.Double", "searchable": False, "filterable": True,
              "retrievable": True, "sortable": True, "facetable": True}
        ],
        "vectorSearch":
        {
            "algorithmConfigurations": [
                {"name": "defaulthnsw", "kind": "hnsw", "hnswParameters": {"metric": "euclidean"}}
            ]
        }
    }

In query's hebben we een identiek filter gebruikt voor zowel prefilter- als postfilterbewerkingen. We hebben een eenvoudig filter gebruikt om ervoor te zorgen dat variaties in de prestaties werden veroorzaakt door de filtermodus en niet de complexiteit van het filter.

Resultaten zijn gemeten in query's per seconde (QPS).

Opgedane kennis

  • Voorfiltering is bijna altijd langzamer dan postfiltering, behalve bij kleine indexen waarbij de prestaties ongeveer gelijk zijn.

  • Bij grotere gegevenssets is prefiltering een langzamere orde van grootte.

  • Waarom wordt de standaardinstelling dus vooraf gefilterd als deze bijna altijd langzamer is? Voorfiltering garandeert dat k resultaten worden geretourneerd als ze aanwezig zijn in de index, waarbij de vooroordelen de voorkeur geven aan relevante overeenkomsten en precisie over snelheid.

  • Postfiltering is bedoeld voor klanten die:

    • waardesnelheid ten opzichte van selectie (postfiltering kan minder dan k resultaten opleveren)
    • filters gebruiken die niet te selectief zijn
    • indexen van voldoende grootte hebben, zodat voorfilteringsprestaties onaanvaardbaar zijn

DETAILS

  • Gegeven een gegevensset met 100.000 vectoren bij 1536 dimensies:

    • Bij het filteren van meer dan 30% van de gegevensset waren prefiltering en postfiltering vergelijkbaar.
    • Bij het filteren van minder dan 0,1% van de gegevensset was prefiltering ongeveer 50% langzamer dan postfiltering.
  • Gegeven een gegevensset met 1 miljoen vectoren bij 1536 dimensies:

    • Bij het filteren van meer dan 30% van de gegevensset was prefiltering ongeveer 30% langzamer.
    • Bij het filteren van minder dan 2% van de gegevensset was prefiltering ongeveer zeven keer langzamer.
  • Gegeven een gegevensset met 1 miljard vectoren bij 96 dimensies:

    • Bij het filteren van meer dan 5% van de gegevensset was prefiltering ongeveer 50% langzamer.
    • Bij het filteren van minder dan 10% van de gegevensset was prefiltering ongeveer zeven keer trager.

In de volgende grafiek ziet u het voorfilter relatieve QPS, berekend als prefilter QPS gedeeld door postfilter QPS.

Chart showing QPS performance for small, medium, and large indexes for relative QPS.

De verticale as is QPS van voorfiltering via QPS van postfiltering. Een waarde van 0,0 betekent bijvoorbeeld dat voorfiltering 100% langzamer is, 0,5 op de verticale as betekent dat voorfiltering 50% langzamer is, 1,0 betekent dat voorfiltering en postfiltering gelijkwaardig zijn.

De horizontale as vertegenwoordigt de filtersnelheid of het percentage kandidaatdocumenten na het toepassen van het filter. Dit betekent bijvoorbeeld 1.00% dat één procent van het zoeklichaam is geselecteerd op basis van de filtercriteria.