Auf dieser Seite wird beschrieben, wie Sie hybride Volltext- und Vektorsuchen in Spanner durchführen. Bei der Hybridsuche wird die Präzision des Abgleichs von Suchbegriffen (Volltextsuche, FTS) mit dem Recall des semantischen Abgleichs (Vektorsuche) kombiniert, um hochrelevante Suchergebnisse zu erzielen.
Spanner unterstützt die folgenden hybriden Suchmuster, die in drei Hauptkategorien unterteilt sind:
| Kategorie | Beschreibung | Primäres Ziel |
| Fusion | Fusion ruft Dokumente unabhängig voneinander ab und sortiert sie mithilfe von Keyword- und Vektorsuche. Anschließend werden die Ergebnisse kombiniert (zusammengeführt). | Durch die Kombination mehrerer Scoring-Signale lassen sich maximaler Recall und maximale Relevanz erzielen. |
| Gefiltert | Mit Keywords wird der Suchbereich gefiltert oder eingegrenzt. | Achten Sie darauf, dass die Keyword-Übereinstimmung eine Voraussetzung ist, während Sie die semantische Relevanz nutzen. |
| ML-Reranking | Ein Machine-Learning-Modell verfeinert eine erste Gruppe von Kandidaten für ein endgültiges, genaueres Ranking. | Die höchstmögliche Genauigkeit für eine kleine endgültige Gruppe von Ergebnissen erzielen. |
Fusionssuche
Bei der Fusionssuche werden FTS und Vektorsuche unabhängig voneinander für denselben Datenkorpus ausgeführt. Anschließend werden die Ergebnisse zusammengeführt, um eine einzige, einheitliche und hochrelevante sortierte Liste zu erstellen.
Sie können zwar unabhängige Abfragen auf der Clientseite ausführen, die hybride Suche in Spanner bietet jedoch die folgenden Vorteile:
- Die Anwendungslogik wird vereinfacht, da parallele Anfragen und das Zusammenführen von Ergebnissen auf dem Server verwaltet werden.
- Es werden keine potenziell großen Zwischenergebnismengen an den Client übertragen.
Sie können SQL verwenden, um Fusionsmethoden in Spanner zu erstellen. In diesem Abschnitt finden Sie Beispiele für Reciprocal Rank Fusion und Relative Score Fusion. Wir empfehlen jedoch, verschiedene Fusionsstrategien zu testen, um herauszufinden, welche am besten zu den Anforderungen Ihrer Anwendung passt.
Rangbasierte Zusammenführung
Verwenden Sie die rangbasierte Fusion, wenn die Relevanzwerte aus verschiedenen Abrufmethoden (z. B. FTS-Werte und Vektorentfernungen) schwer zu vergleichen oder zu normalisieren sind, da sie in verschiedenen Bereichen gemessen werden. Bei dieser Methode wird die Rangposition jedes Dokuments aus jedem Retriever verwendet, um einen endgültigen Wert und ein endgültiges Ranking zu generieren.
Reciprocal Rank Fusion (RRF) ist eine rangbasierte Fusionsfunktion. Der RRF-Wert für ein Dokument ist die Summe der Kehrwerte seiner Ränge aus mehreren Abrufern und wird so berechnet:
\[ score\ (d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}(1\ /\ (\ 𝑘\ +\ ran{k}_{r}\ (𝑑)\ )\ )\ \]
Wobei:
- d ist das Dokument.
- R ist die Menge der Retriever (FTS und Vektorsuche).
- k ist eine Konstante (oft auf 60 festgelegt), mit der der Einfluss von Dokumenten mit sehr hohem Ranking moderiert wird.
- w ist der Rang des Dokuments aus dem Retriever r.
RRF in einer Spanner-Abfrage implementieren
Vektormesswerte (z. B. APPROX_DOT_PRODUCT) und Textsuchergebnisse (z. B. SCORE_NGRAMS) werden auf inkompatiblen Skalen gemessen. Im folgenden Beispiel wird RRF implementiert, um Daten anhand der Rangposition statt anhand von Rohwerten zu normalisieren.
Mit der Abfrage wird UNNEST(ARRAY(...) WITH OFFSET verwendet, um den 100 besten Kandidaten jeder Methode einen Rang zuzuweisen. Anschließend wird anhand der Umkehrung dieser Ränge eine standardisierte Punktzahl berechnet und die Ergebnisse werden aggregiert, um die fünf besten Übereinstimmungen zurückzugeben.
SELECT SUM(1 / (60 + rank)) AS rrf_score, key
FROM (
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY APPROX_DOT_PRODUCT(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
UNION ALL
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'foo')
ORDER BY SCORE_NGRAMS(text_tokens_ngrams, 'foo') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
)
GROUP BY key
ORDER BY rrf_score DESC
LIMIT 5;
Scorebasierte Zusammenführung
Die scorebasierte Zusammenführung ist effektiv, wenn die Relevanzscores der verschiedenen Methoden vergleichbar sind oder Sie sie normalisieren können. Dies kann ein genaueres Ranking ermöglichen, das das tatsächliche Relevanzgewicht jeder Methode berücksichtigt.
Relative Score Fusion (RSF) ist eine scorebasierte Methode, mit der Scores aus verschiedenen Methoden relativ zu den höchsten und niedrigsten Scores innerhalb der jeweiligen Methode normalisiert werden. Dazu werden in der Regel die Funktionen MIN() und MAX() verwendet. Die RSF-Punktzahl eines Dokuments, das von einer Gruppe von Retrievern abgerufen wird, wird so berechnet:
\[ score(d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}({w}_{r}*(scor{e}_{r}(d)\ -\ mi{n}_{r})\ /\ (ma{x}_{r\ }-mi{n}_{r})\ ) \]
Wobei:
- d ist das Dokument.
- R ist die Menge der Retriever (FTS und Vektorsuche).
- w ist das Gewicht, das einem bestimmten Retriever zugewiesen ist.
RSF in einer Spanner-Abfrage implementieren
Um RSF zu implementieren, müssen Sie die Werte aus dem Vektor und dem FTS auf eine gemeinsame Skala normalisieren. Im folgenden Beispiel werden die Mindest- und Höchstpunktzahlen in separaten WITH-Klauseln berechnet, um die Normalisierungsfaktoren abzuleiten. Die Ergebnisse werden dann mit einem FULL OUTER JOIN kombiniert, indem die normalisierten Werte aus der ANN-Suche (Approximate Nearest Neighbor, ungefähre Suche nach dem nächsten Nachbarn), die aus cosine_distance konvertiert wurden, und der FTS addiert werden.
WITH ann AS (
SELECT key, APPROX_COSINE_DISTANCE(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') AS cosine_distance,
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY cosine_distance
LIMIT 100
),
fts AS (
SELECT key, SCORE_NGRAMS(text_tokens_ngrams, 'Green') AS score,
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'Green')
ORDER BY score DESC
LIMIT 100
),
ann_min AS (
SELECT MIN(1 - cosine_distance) AS min
FROM ann
),
ann_max AS (
SELECT MAX(1 - cosine_distance) AS max
FROM ann
),
fts_min AS (
SELECT MIN(score) AS min
FROM fts
),
fts_max AS (
SELECT MAX(score) AS max
FROM fts
)
SELECT IFNULL(ann.key, fts.key),
IFNULL(((1 - ann.cosine_distance) - ann_min.min) /
(ann_max.max - ann_min.min), 0) +
IFNULL((fts.score - fts_min.min) /
(fts_max.max - fts_min.min), 0) AS score
FROM ann
FULL OUTER JOIN fts
ON ann.key = fts.key
CROSS JOIN ann_min
CROSS JOIN ann_max
CROSS JOIN fts_min
CROSS JOIN fts_max
ORDER BY score DESC
LIMIT 5;
Gefilterte Suche
Bei gefilterten Suchanfragen wird FTS verwendet, um einen Filter zu erstellen, der die Menge der Dokumente reduziert, die für eine KNN-Vektorsuche (k-Nearest Neighbors) berücksichtigt werden. Optional können Sie die Größe der Ergebnismenge durch Vorsortieren begrenzen.
Gefilterte Suche in einer Spanner-Abfrage implementieren
Bei der Beispielsuche in diesem Abschnitt wird der Vektorsuchraum in den folgenden Schritten auf die Teilmenge der Daten eingegrenzt, die den Keywords entsprechen:
- Mit
SEARCH (text_tokens, 'Green')werden Zeilen gesucht, in denen die Spaltetext_tokensden TextGreenenthält. Die 1.000 wichtigsten Zeilen werden in einer durch den Suchindex definierten Sortierreihenfolge zurückgegeben. - Verwendet eine Vektorfunktion,
DOT_PRODUCT(@vector, embedding), um die Ähnlichkeit zwischen dem Abfragevektor (@vector) und dem gespeicherten Dokumentvektor (Einbettung) zu berechnen. Anschließend werden die Ergebnisse sortiert und die 10 besten Ergebnisse zurückgegeben.
SELECT key
FROM (
SELECT key, embedding
FROM hybrid_search
WHERE SEARCH (text_tokens, 'Green')
ORDER BY presort
LIMIT 1000)
ORDER BY DOT_PRODUCT(@vector, embedding) DESC
LIMIT 10;
ML-Neuberechnung des Ranks
Das ML-basierte Neuklassifizieren ist ein rechenintensiver, aber sehr präziser Ansatz. Dabei wird ein Modell für maschinelles Lernen auf eine kleine Kandidatengruppe angewendet, die durch FTS, die Vektorsuche oder eine Kombination aus beidem reduziert wurde. Weitere Informationen zur Einbindung von Spanner Vertex AI finden Sie in der Übersicht zur Einbindung von Spanner Vertex AI.
Sie können das ML-Reranking mit der Spanner-Funktion ML.PREDICT in ein bereitgestelltes Vertex AI-Modell einbinden.
ML-basiertes Neuklassifizieren implementieren
- Stellen Sie ein Reranker-Modell (z. B. von HuggingFace) in einem Vertex AI-Endpunkt bereit.
Erstellen Sie ein Spanner-
MODEL-Objekt, das auf den Vertex AI-Endpunkt verweist. Zum Beispiel im folgendenReranker-Modellbeispiel:text ARRAY<string(max)>sind die Dokumente.text_pair ARRAY<string(max)>ist der Abfragetext im Beispiel.scoresind die Relevanzwerte, die vom ML-Modell für die Eingabepaare von Texten zugewiesen werden.
CREATE MODEL Reranker INPUT (text ARRAY<string(max)>, text_pair ARRAY<string(max)>) OUTPUT (score FLOAT32) REMOTE OPTIONS ( endpoint = '...' );Verwenden Sie eine Unterabfrage, um die ersten Kandidaten abzurufen (z. B. die 100 besten Ergebnisse einer ANN-Suche) und an
ML.PREDICTzu übergeben. Die Funktion gibt eine neue Spalte mit dem Score für die endgültige Sortierung zurück.SELECT key FROM ML.PREDICT( MODEL Reranker, ( SELECT key, text, "gift for 8-year-old" AS text_pair FROM hybrid_search WHERE embedding IS NOT NULL ORDER BY APPROX_DOT_PRODUCT(@vector, embedding, options=>JSON '{"num_leaves_to_search": 50}') DESC LIMIT 100) ) ORDER BY score DESC LIMIT 3;
Nächste Schritte
- Suchmaschine mit KI-basierter Hybridsuche in Spanner anpassen:
- Weitere Informationen zur Volltextsuche