Mit Vektoreinbettungen suchen
Auf dieser Seite wird beschrieben, wie Sie Firestore verwenden, um mit den folgenden Verfahren Vektorsuchen nach KNN-Nachbarn (KNNN-Near Nearest) durchzuführen:
- Vektorwerte speichern
- KNN-Vektorindexe erstellen und verwalten
- Führen Sie eine KNN-Abfrage (K-nearest-Nachbar) mit einer der unterstützten Vektorentfernungsfunktionen aus.
Vektoreinbettungen speichern
Sie können Vektorwerte wie Texteinbettungen aus Ihren Firestore-Daten erstellen und in Firestore-Dokumenten speichern.
Schreibvorgang mit einer Vektoreinbettung
Das folgende Beispiel zeigt, wie Sie eine Vektoreinbettung in einem Firestore-Dokument speichern:
Python
from google.cloud import firestore from google.cloud.firestore_v1.vector import Vector collection = firestore_client.collection("coffee-beans") doc = { "name": "Kahawa coffee beans" "description": "Information about the Kahawa coffee beans." "embedding_field": Vector([1.0 , 2.0, 3.0]) } collection.add(doc)
Node.js
import { Firestore, FieldValue, } from "@google-cloud/firestore"; const db = new Firestore(); const coll = db.collection('coffee-beans'); await coll.add({ name: "Kahawa coffee beans", description: "Information about the Kahawa coffee beans.", embedding_field: FieldValue.vector([1.0 , 2.0, 3.0]) });
Vektoreinbettungen mit einer Cloud Function berechnen
Zum Berechnen und Speichern von Vektoreinbettungen können Sie eine Cloud Functions-Funktion einrichten, wenn ein Dokument aktualisiert oder erstellt wird:
Python
@functions_framework.cloud_event def store_embedding(cloud_event) -> None: """Triggers by a change to a Firestore document. """ firestore_payload = firestore.DocumentEventData() payload = firestore_payload._pb.ParseFromString(cloud_event.data) collection_id, doc_id = from_payload(payload) # Call a function to calculate the embedding embedding = calculate_embedding(payload) # Update the document doc = firestore_client.collection(collection_id).document(doc_id) doc.set({"embedding_field": embedding}, merge=True)
Node.js
/** * A vector embedding will be computed from the * value of the `content` field. The vector value * will be stored in the `embedding` field. The * field names `content` and `embedding` are arbitrary * field names chosen for this example. */ async function storeEmbedding(event: FirestoreEvent<any>): Promise<void> { // Get the previous value of the document's `content` field. const previousDocumentSnapshot = event.data.before as QueryDocumentSnapshot; const previousContent = previousDocumentSnapshot.get("content"); // Get the current value of the document's `content` field. const currentDocumentSnapshot = event.data.after as QueryDocumentSnapshot; const currentContent = currentDocumentSnapshot.get("content"); // Don't update the embedding if the content field did not change if (previousContent === currentContent) { return; } // Call a function to calculate the embedding for the value // of the `content` field. const embeddingVector = calculateEmbedding(currentContent); // Update the `embedding` field on the document. await currentDocumentSnapshot.ref.update({ embedding: embeddingVector, }); }
Vektorindexe erstellen und verwalten
Bevor Sie mit Ihren Vektoreinbettungen eine Suche nach dem nächsten Nachbarn durchführen können, müssen Sie einen entsprechenden Index erstellen. Die folgenden Beispiele zeigen, wie Vektorindexe erstellt und verwaltet werden.
Einzelfeldvektorindex erstellen
Verwenden Sie gcloud alpha firestore indexes composite create
, um einen Einzelfeldvektorindex zu erstellen:
gcloud
gcloud alpha firestore indexes composite create \ --collection-group=collection-group \ --query-scope=COLLECTION \ --field-config field-path=vector-field,vector-config='vector-configuration' \ --database=database-id
Dabei gilt:
- collection-group ist die ID der Sammlungsgruppe.
- vector-field ist der Name des Felds, das die Vektoreinbettung enthält.
- database-id ist die ID der Datenbank.
- vector-configuration enthält den Vektor
dimension
und den Indextyp.dimension
ist eine Ganzzahl bis 2.048. Der Indextyp mussflat
sein. Formatieren Sie die Indexkonfiguration so:{"dimension":"DIMENSION", "flat": "{}"}
.
Zusammengesetzten Vektorindex erstellen
Im folgenden Beispiel werden ein zusammengesetzter Vektorindex für das Feld color
und ein Feld zur Vektoreinbettung erstellt.
gcloud
gcloud alpha firestore indexes composite create \ --collection-group=collection-group \ --query-scope=COLLECTION \ --field-config=order=ASCENDING,field-path="color" \ --field-config field-path=field,vector-config='{"dimension":"1024", "flat": "{}"}' \ --database=database-id
Alle Vektorindexe auflisten
gcloud
gcloud alpha firestore indexes composite list --database=database-id
Ersetzen Sie database-id durch die ID der Datenbank.
Vektorindex löschen
gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
Dabei gilt:
- index-id ist die ID des zu löschenden Index.
Verwenden Sie
indexes composite list
, um die Index-ID abzurufen. - database-id ist die ID der Datenbank.
Einen Vektorindex beschreiben
gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
Dabei gilt:
- index-id ist die ID des zu beschreibenden Index. Verwenden Sie oder
indexes composite list
, um die Index-ID abzurufen. - database-id ist die ID der Datenbank.
Abfrage für den nächsten Nachbarn erstellen
Sie können eine Ähnlichkeitssuche durchführen, um die nächsten Nachbarn einer Vektoreinbettung zu finden. Für Ähnlichkeitssuchen sind Vektorindexe erforderlich. Wenn kein Index vorhanden ist, schlägt Firestore einen Index vor, der über die gcloud CLI erstellt werden soll.
Python
from google.cloud.firestore_v1.base_vector_query import DistanceMeasure collection = collection("coffee-beans") // Requires vector index collection.find_nearest( vector_field="embedding_field", query_vector=Vector([3.0, 1.0, 2.0]), distance_measure=DistanceMeasure.EUCLIDEAN, limit=5)
Node.js
import { Firestore, FieldValue, VectorQuery, VectorQuerySnapshot, } from "@google-cloud/firestore"; // Requires single-field vector index const vectorQuery: VectorQuery = coll.findNearest('embedding_field', FieldValue.vector([3.0, 1.0, 2.0]), { limit: 5, distanceMeasure: 'EUCLIDEAN' }); const vectorQuerySnapshot: VectorQuerySnapshot = await vectorQuery.get();
Vektorentfernungen
Bei Abfragen des nächsten Nachbarn werden die folgenden Optionen für die Vektorentfernung unterstützt:
EUCLIDEAN
: Misst die EUCLIDEAN-Entfernung zwischen den Vektoren. Weitere Informationen finden Sie unter Euklidisch.COSINE
: vergleicht Vektoren anhand des Winkels, sodass Sie Ähnlichkeiten messen können, die nicht auf der Größe der Vektoren basieren. Wir empfehlen die Verwendung vonDOT_PRODUCT
mit normalisierten Vektoren mit Einheit anstelle der COSINE-Entfernung, die mathematisch gleichwertig mit einer besseren Leistung ist. Weitere Informationen finden Sie unter Kosinus-Ähnlichkeit.DOT_PRODUCT
: Ähnlich wieCOSINE
, wird aber von der Größe der Vektoren beeinflusst. Weitere Informationen finden Sie unter Dot-Produkt.
Daten vorfiltern
Um Daten vorzufiltern, bevor die nächsten Nachbarn gefunden werden, können Sie eine Ähnlichkeitssuche mit anderen Filtern kombinieren, außer mit Ungleichheitsfiltern. Die zusammengesetzten and
- und or
-Filter werden unterstützt. Für Feldfilter werden die folgenden Filter unterstützt:
==
gleichin
array_contains
array_contains_any
Python
// Similarity search with pre-filter // Requires composite vector index collection.where("color", "==", "red").find_nearest( vector_field="embedding_field", query_vector=Vector([3.0, 1.0, 2.0]), distance_measure=DistanceMeasure.EUCLIDEAN, limit=5)
Node.js
// Similarity search with pre-filter // Requires composite vector index const preFilteredVectorQuery: VectorQuery = coll .where("color", "==", "red") .findNearest("embedding_field", FieldValue.vector([3.0, 1.0, 2.0]), { limit: 5, distanceMeasure: "EUCLIDEAN", }); vectorQueryResults = await preFilteredVectorQuery.get();
Beschränkungen
Beachten Sie bei der Arbeit mit Vektoreinbettungen die folgenden Einschränkungen:
- Die maximal unterstützte Einbettungsdimension ist 2.048. Zum Speichern größerer Indexe verwenden Sie die Dimensionalitätsreduktion.
- Die maximale Anzahl von Dokumenten, die von einer Abfrage zum nächsten Nachbarn zurückgegeben werden können, beträgt 1.000.
- Die Vektorsuche unterstützt keine Echtzeit-Snapshot-Listener.
- Ungleichheitsfilter können nicht zum Vorfiltern von Daten verwendet werden.
- Nur die Python- und Node.js-Clientbibliotheken unterstützen die Vektorsuche.
Nächste Schritte
- Best Practices für Firestore
- Lese- und Schreibvorgänge in großem Maßstab verstehen