Auf dieser Seite wird beschrieben, wie Sie in Spanner eine Suche nach Vektorähnlichkeit durchführen, indem Sie die Vektorfunktionen für Kosinus-Abstand, euklidischen Abstand und Punktprodukt verwenden, um die K-nächsten Nachbarn zu finden. Diese Informationen gelten sowohl für Datenbanken mit GoogleSQL-Dialekt als auch für Datenbanken mit PostgreSQL-Dialekt. Bevor Sie diese Seite lesen, sollten Sie sich mit den folgenden Konzepten vertraut machen:
- Euklidischer Abstand: Misst den kürzesten Abstand zwischen zwei Vektoren.
- Kosinus-Distanz: Hier wird der Kosinus des Winkels zwischen zwei Vektoren gemessen.
- Skalarprodukt: Hier wird der Kosinus des Winkels multipliziert mit dem Produkt der entsprechenden Vektormagnituden berechnet. Wenn Sie wissen, dass alle Vektoreinbettungen in Ihrem Dataset normalisiert sind, können Sie
DOT_PRODUCT()
als Distanzfunktion verwenden. - K-Nearest Neighbors (KNN): Ein Algorithmus für überwachtes maschinelles Lernen, der zur Lösung von Klassifizierungs- oder Regressionsproblemen verwendet wird.
Sie können Vektorentfernungsfunktionen verwenden, um die KNN-Vektorsuche (K-Nearest Neighbors) für Anwendungsfälle wie die Ähnlichkeitssuche oder die Retrieval-Augmented Generation durchzuführen. Spanner unterstützt die Funktionen COSINE_DISTANCE()
, EUCLIDEAN_DISTANCE()
und DOT_PRODUCT()
, die für Vektoreinbettungen verwendet werden. Damit können Sie die KNN der Eingabeeinbettung ermitteln.
Nachdem Sie beispielsweise Ihre operativen Spanner-Daten als Vektoreinbettungen generiert und gespeichert haben, können Sie diese Vektoreinbettungen als Eingabeparameter in Ihrer Abfrage angeben, um die nächstgelegenen Vektoren im N-dimensionalen Raum zu finden und nach semantisch ähnlichen oder verwandten Elementen zu suchen.
Alle drei Distanzfunktionen verwenden die Argumente vector1
und vector2
vom Typ array<>
, die aus denselben Dimensionen bestehen und dieselbe Länge haben müssen. Weitere Informationen zu diesen Funktionen finden Sie hier:
COSINE_DISTANCE()
in GoogleSQLEUCLIDEAN_DISTANCE()
in GoogleSQLDOT_PRODUCT()
in GoogleSQL- Mathematische Funktionen in PostgreSQL
(
spanner.cosine_distance()
,spanner.euclidean_distance()
undspanner.dot_product()
) - Vektordistanzfunktionen auswählen, um die Ähnlichkeit von Vektoreinbettungen zu messen
Beispiele
Die folgenden Beispiele zeigen die KNN-Suche, die KNN-Suche über partitionierte Daten und die Verwendung eines sekundären Index mit KNN.
In allen Beispielen wird EUCLIDEAN_DISTANCE()
verwendet. Sie können auch COSINE_DISTANCE()
verwenden. Wenn alle Vektoreinbettungen in Ihrem Dataset normalisiert sind, können Sie außerdem DOT_PRODUCT()
als Distanzfunktion verwenden.
Beispiel 1: KNN-Suche
Angenommen, es gibt eine Tabelle Documents
mit einer Spalte (DocEmbedding
) mit vorab berechneten Texteinbettungen aus der Spalte DocContents
(Bytes).
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32>
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE Documents (
UserId bigint NOT NULL,
DocId bigint NOT NULL,
Author varchar(1024),
DocContents bytea,
DocEmbedding float4[],
PRIMARY KEY (UserId, DocId)
);
Angenommen, eine Eingabe-Einbettung für „Baseball, aber nicht professioneller Baseball“ ist das Array [0.3, 0.3, 0.7, 0.7]
. Mit der folgenden Anfrage können Sie die fünf ähnlichsten Dokumente finden, die übereinstimmen:
GoogleSQL
SELECT DocId, DocEmbedding FROM Documents
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;
PostgreSQL
SELECT DocId, DocEmbedding FROM Documents
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;
Die erwarteten Ergebnisse dieses Beispiels:
Documents
+---------------------------+-----------------+
| DocId | DocEmbedding |
+---------------------------+-----------------+
| 24 | [8, ...] |
+---------------------------+-----------------+
| 25 | [6, ...] |
+---------------------------+-----------------+
| 26 | [3.2, ...] |
+---------------------------+-----------------+
| 27 | [38, ...] |
+---------------------------+-----------------+
| 14229 | [1.6, ...] |
+---------------------------+-----------------+
Beispiel 2: KNN-Suche in partitionierten Daten
Die Abfrage im vorherigen Beispiel kann geändert werden, indem der WHERE
-Klausel Bedingungen hinzugefügt werden, um die Vektorsuche auf eine Teilmenge Ihrer Daten zu beschränken. Eine häufige Anwendung ist die Suche in partitionierten Daten, z. B. in Zeilen, die zu einem bestimmten UserId
gehören.
GoogleSQL
SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;
PostgreSQL
SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;
Die erwarteten Ergebnisse dieses Beispiels:
Documents
+-----------+-----------------+-----------------+
| UserId | DocId | DocEmbedding |
+-----------+-----------------+-----------------+
| 18 | 234 | [12, ...] |
+-----------+-----------------+-----------------+
| 18 | 12 | [1.6, ...] |
+-----------+-----------------+-----------------+
| 18 | 321 | [22, ...] |
+-----------+-----------------+-----------------+
| 18 | 432 | [3, ...] |
+-----------+-----------------+-----------------+
Beispiel 3: KNN-Suche über sekundäre Indexbereiche
Wenn der Filter der WHERE
-Klausel, die Sie verwenden, nicht Teil des Primärschlüssels der Tabelle ist, können Sie einen sekundären Index erstellen, um den Vorgang mit einem Index-Only-Scan zu beschleunigen.
GoogleSQL
CREATE INDEX DocsByAuthor
ON Documents(Author)
STORING (DocEmbedding);
SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
<embeddings for "book about the time traveling American">)
LIMIT 5;
PostgreSQL
CREATE INDEX DocsByAuthor
ON Documents(Author)
INCLUDE (DocEmbedding);
SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY spanner.euclidean_distance(DocEmbedding,
<embeddings for "that book about the time traveling American">)
LIMIT 5;
Die erwarteten Ergebnisse dieses Beispiels:
Documents
+------------+-----------------+-----------------+
| Author | DocId | DocEmbedding |
+------------+-----------------+-----------------+
| Mark Twain | 234 | [12, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 12 | [1.6, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 321 | [22, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 432 | [3, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 375 | [9, ...] |
+------------+-----------------+-----------------+