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.
Hinweis
strictPostFilter befindet sich derzeit in der öffentlichen Vorschau. Diese Vorschau wird ohne Vereinbarung auf Serviceebene bereitgestellt und wird für Produktionsworkloads nicht empfohlen. Bestimmte Features werden möglicherweise nicht unterstützt oder weisen eingeschränkte Funktionen auf. Weitere Informationen finden Sie unter Supplementale Nutzungsbedingungen für Microsoft Azure Previews.
prefilter und postfilter sind in der Regel in der neuesten stabilen REST-API-Version verfügbar.
In Azure KI-Suche können Sie einen Filterausdruck verwenden, um einer vectorabfrage Einschluss- oder Ausschlusskriterien hinzuzufügen. Sie können auch einen Filtermodus angeben, der den Filter anwendet:
- Vor der Abfrageausführung, die als Vorabfilterung bezeichnet wird.
- Nach der Abfrageausführung, die als Postfilterung bezeichnet wird.
- Nachdem die globalen Top-Ergebnisse
kidentifiziert wurden, ist dies bekannt als strikte Nachfilterung (Vorschau).
In diesem Artikel wird REST zur Veranschaulichung verwendet. Codebeispiele in anderen Sprachen und End-to-End-Lösungen, die Vektorabfragen enthalten, finden Sie im Repository azure-search-vector-samples GitHub.
Sie können auch Search Explorer im Azure-Portal verwenden, um Vektorinhalte abzufragen. In der JSON-Ansicht können Sie Filter hinzufügen und den Filtermodus angeben.
Funktionsweise des Filterns in Vektorabfragen
Azure KI-Suche verwendet den hierarchischen Navigable Small World (HNSW)-Algorithmus für die Suche nach nähersten Nachbarn (ANN), wobei HNSW-Diagramme über mehrere Shards hinweg gespeichert werden. Jeder Shard enthält einen Teil des gesamten Indexes.
Filter gelten für filterableNichtvektorfelder , entweder Zeichenfolgen oder numerische Felder, um Suchdokumente basierend auf Filterkriterien einzuschließen oder auszuschließen. Vektorfelder selbst sind nicht filterbar, Sie können jedoch Filter für andere Felder im selben Index verwenden, um die Dokumente einzuschränken, die für die Vektorsuche berücksichtigt werden. Wenn Ihr Index keine geeigneten Text- oder numerischen Felder aufweist, überprüfen Sie die Dokumentmetadaten, die bei der Filterung hilfreich sein können, wie z. B. LastModified oder CreatedBy Eigenschaften.
Der vectorFilterMode Parameter steuert, wo Filtervorgänge während der Suchphasen angewendet werden, was sich darauf auswirkt, wie die Ergebnisse auf eine Teilmenge von Elementen gefiltert werden (z. B. nach Kategorie, Tag oder anderen Attributen), und wirkt sich auf Latenz, Rückruf und Durchsatz aus. Es gibt drei Modi:
preFilterwendet den Filter während der HNSW-Traversierung auf jedes Segment an. Dieser Modus maximiert den Rückruf, kann aber mehr des Diagramms durchlaufen und die CPU- und Latenzzeit für hoch selektive Filter erhöhen.postFilterführt HNSW-Traversierung und -Filterung unabhängig auf jedem Shard durch, schneidet Ergebnisse auf Shard-Ebene und aggregiert dann die oberenkErgebnisse von jedem Shard in eine globale Top-Listek. Dieser Modus kann falsche Negative für hoch selektive Filter oder kleinekWerte erstellen.strictPostFilter(Vorschau) erkennt die ungefilterte globale Topk, bevor der Filter angewendet wird. Dieser Modus hat das höchste Risiko, falsch negative Ergebnisse für hoch selektive Filter und kleinekWerte zurückzugeben.
Weitere Informationen zu diesen Modi finden Sie unter Festlegen des Filtermodus.
Definieren eines Filters
Filter bestimmen den Umfang von Vektorabfragen und werden mithilfe von Dokumenten: Search Post (REST API) definiert. Wenn Sie kein Vorschaufeature verwenden möchten, verwenden Sie die neueste stabile Version der REST-APIs des Suchdiensts , um die Anforderung zu formulieren.
Diese REST-API bietet Folgendes:
-
filterfür die Kriterien. -
vectorFilterModeum anzugeben, wann der Filter während der Vektorabfrage angewendet wird. Unterstützte Modi finden Sie unter "Festlegen des Filtermodus".
POST https://{search-endpoint}/indexes/{index-name}/docs/search?api-version={api-version}
Content-Type: application/json
api-key: {admin-api-key}
{
"count": true,
"select": "title, content, category",
"filter": "category eq 'Databases'",
"vectorFilterMode": "preFilter",
"vectorQueries": [
{
"kind": "vector",
"vector": [
-0.009154141,
0.018708462,
. . . // Trimmed for readability
-0.02178128,
-0.00086512347
],
"fields": "contentVector",
"k": 50
}
]
}
In diesem Beispiel zielt die Einbettung des Vektors auf das contentVector Feld ab, und die Filterkriterien gelten für categoryein filterbares Textfeld. Da der preFilter Modus verwendet wird, wird der Filter angewendet, bevor die Suchmaschine die Abfrage ausführt, sodass nur Dokumente in der Kategorie während der Databases Vektorsuche berücksichtigt werden.
Festlegen des Filtermodus
Der vectorFilterMode Parameter bestimmt, wann und wie der Filter relativ zur Vektorabfrageausführung angewendet wird. Sie können die folgenden Modi verwenden:
-
preFilter(empfohlen) postFilter-
strictPostFilter(Vorschau)
Hinweis
preFilter ist die Standardeinstellung für Indizes, die nach ungefähr dem 15. Oktober 2023 erstellt wurden. Für Indizes, die vor diesem Datum erstellt wurden, postFilter ist die Standardeinstellung. Um erweiterte Vektorfeatures wie z. B. die Vektorkomprimierung zu verwenden preFilter , müssen Sie den Index neu erstellen.
Sie können die Kompatibilität testen, indem Sie eine Vektorabfrage mit "vectorFilterMode": "preFilter" der 2023-10-01-preview REST-API-Version oder höher senden. Wenn die Abfrage fehlschlägt, unterstützt Ihr Index preFilter nicht.
Vorfilterung wendet Filter vor der Abfrageausführung an, wodurch der Kandidatensatz für den Vektorsuchalgorithmus reduziert wird. Die oberstenk Ergebnisse werden dann aus diesem gefilterten Satz ausgewählt.
Bei einer Vektorabfrage ist preFilter der Standardmodus, da Qualität und Rückruf gegenüber der Latenz begünstigt werden.
Funktionsweise dieses Modus
Wenden Sie auf jeden Shard das Filter-Prädikat während des HNSW-Traversals an und erweitern Sie den Graph, bis
kKandidaten gefunden werden.Produzieren Sie die vorfilterten lokalen Topergebnisse
kpro Shard.Aggregieren Sie die gefilterten Ergebnisse zu einer globalen Top-Ergebnismenge
k.
Auswirkung dieses Modus
Traversal erweitert die Suchoberfläche, um mehr gefilterte Kandidaten zu finden, insbesondere, wenn der Filter selektiv ist. Dies erzeugt die am ehesten ähnlichen Top-k-Ergebnisse über sämtliche Shards. Jeder Shard identifiziert die k Ergebnisse, die das Filter-Prädikat erfüllen.
Vorfilterung garantiert, dass k Ergebnisse zurückgegeben werden, wenn sie im Index vorhanden sind. Bei hoch selektiven Filtern kann dies dazu führen, dass ein erheblicher Teil des Diagramms durchlaufen wird, wodurch die Berechnungskosten und Latenz erhöht werden, während der Durchsatz reduziert wird. Wenn Ihr Filter sehr selektiv ist (hat nur wenige Übereinstimmungen), sollten Sie in Betracht ziehen, exhaustive: true zu verwenden, um eine erschöpfende Suche durchzuführen.
Vergleichstabelle
| Modus | Rückruf (gefilterte Ergebnisse) | Rechenkosten | Risiko falsch negativer Ergebnisse | Wann verwendet werden soll |
|---|---|---|---|---|
preFilter |
Sehr hoch | Höher (erhöht sich mit Filterauswahl und Komplexität) | Kein Risiko |
Empfohlene Standardeinstellung für alle Szenarien, insbesondere wenn der Rückruf kritisch ist (vertrauliche Suchdomänen), bei verwendung selektiver Filter oder bei Verwendung kleiner k. |
postFilter |
Mittel bis hoch (verringert sich durch selektive Filterung) | Ähnlich wie ungefiltert, erhöht sich aber mit der Filterkomplexität | Moderat (Kann Übereinstimmungen pro Shard verpassen) | Eine Option für Filter, die nicht zu selektiv sind, und für höherwertigek Abfragen. |
strictPostFilter |
Niedrigste (verringert sich am schnellsten bei Filterselektivität) | Ähnlich wie ungefiltert | Höchstergebnis (kann null bis keine Ergebnisse für ausgewählte Filter oder kleine k ergeben) |
Eine Option für Faceted Search-Anwendungen, bei denen mehr Ergebnisse nach der Filteranwendung angezeigt werden, beeinflusst die Benutzererfahrung stärker als das Risiko falsch negativer Ergebnisse. Verwenden Sie nicht mit kleinen k. |
Benchmarktests für Vorfilterung und Nachfilterung
Wichtig
Dieser Abschnitt bezieht sich auf Vorfilterung und Nachfilterung, nicht auf strikte Nachfilterung.
Um die Bedingungen zu verstehen, unter denen ein Filtermodus besser als der andere funktioniert, haben wir eine Reihe von Tests ausgeführt, um Abfrageergebnisse über kleine, mittlere und große Indizes auszuwerten.
- Klein (100.000 Dokumente, 2,5 GB Index, 1.536 Dimensionen)
- Mittel (1 Millionen Dokumente, 25 GB Index, 1.536 Dimensionen)
- Groß (1 Milliarden Dokumente, 1,9 TB Index, 96 Dimensionen)
Für die kleinen und mittleren Workloads haben wir einen Standard 2 (S2)-Dienst mit einer Partition und einem Replikat verwendet. Für die große Workload haben wir einen Standard 3 (S3)-Dienst mit 12 Partitionen und einem Replikat verwendet.
Indizes hatten eine identische Konstruktion: ein Schlüsselfeld, ein Vektorfeld, ein Textfeld und ein numerisches filterbares Feld. Der folgende Index wird mithilfe der 2023-11-01 Syntax definiert.
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,
"vectorSearchProfile": "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": {
"algorithms": [
{
"name": "defaulthnsw",
"kind": "hnsw",
"hnswParameters": { "metric": "euclidean" }
}
],
"profiles": [
{
"name": "defaulthnsw",
"algorithm": "defaulthnsw"
}
]
}
}
In Abfragen haben wir einen identischen Filter sowohl für Prefilter- als auch für Postfiltervorgänge verwendet. Wir haben einen einfachen Filter verwendet, um sicherzustellen, dass Abweichungen in der Leistung aufgrund des Filtermodus und nicht der Filterkomplexität zurückzuführen waren.
Die Ergebnisse wurden in Abfragen pro Sekunde (QPS) gemessen.
Erkenntnisse
Die Vorfilterung ist fast immer langsamer als die Nachfilterung, außer bei kleinen Indizes, bei denen die Leistung ungefähr gleich ist.
Bei größeren Datasets ist die Vorfilterung um Größenordnungen langsamer.
Warum ist das Vorfilteren die Standardeinstellung, wenn es fast immer langsamer ist? Durch die Vorfilterung wird sichergestellt, dass
kErgebnisse zurückgegeben werden, wenn sie im Index vorhanden sind, wobei die Verzerrung den Rückruf und die Genauigkeit gegenüber der Geschwindigkeit begünstigt.Verwenden Sie die Nachfilterung, wenn Sie:
Priorisieren Sie Geschwindigkeit vor Auswahl (die Nachfilterung kann weniger als
kErgebnisse liefern).Verwenden Sie Filter, die nicht übermäßig selektiv sind.
Verfügen Sie über Indizes ausreichender Größe, sodass die Vorfilter-Leistung inakzeptabel ist.
Details
Angesichts eines Datasets mit 100.000 Vektoren bei 1.536 Dimensionen:
Bei der Filterung von mehr als 30% des Datasets waren Vorfilterung und Nachfilterung vergleichbar.
Beim Filtern von weniger als 0,1% des Datasets betrug die Vorfilterung etwa 50% langsamer als die Nachfilterung.
Angesichts eines Datasets mit 1 Millionen Vektoren bei 1.536 Dimensionen:
Bei der Filterung von mehr als 30% des Datasets war die Vorfilterung etwa 30% langsamer.
Bei der Filterung von weniger als 2% des Datasets war die Vorfilterung etwa siebenmal langsamer.
Angesichts eines Datasets mit 1 Milliarden Vektoren mit 96 Dimensionen:
Beim Filtern von mehr als 5% des Datasets war die Vorfilterung etwa 50% langsamer.
Bei der Filterung von weniger als 10% des Datasets war die Vorfilterung etwa siebenmal langsamer.
Die folgende Abbildung zeigt die relative Präfilter-QPS, berechnet als das Verhältnis der Präfilter-QPS geteilt durch die Postfilter-QPS.
Die vertikale Achse stellt die relative Leistung der Vorfilterung im Vergleich zur Postfilterung dar, ausgedrückt als Verhältnis von QPS (Abfragen pro Sekunde). Zum Beispiel:
- Ein Wert von
0.0bedeutet, dass das Vorfiltern 100 % langsamer ist als das Nachfiltern. - Ein Wert von
0.5bedeutet, dass die Vorfilterung um 50 % langsamer ist. - Ein Wert von
1.0bedeutet, dass Vorfiltern und Nachfiltern gleichwertig sind.
Die horizontale Achse stellt die Filterrate oder den Prozentsatz der Kandidatendokumente nach dem Anwenden des Filters dar. Eine Rate von 1.00% bedeutet beispielsweise, dass die Filterkriterien einen Prozent des Suchkorpus identifiziert haben.