Mit Vektoreinbettungen suchen
Auf dieser Seite erfahren Sie, wie Sie mithilfe von Firestore K-nearest ausführen Nachbarvektoren (KNN-Vektoren) wird mit den folgenden Techniken gesucht:
- Vektorwerte speichern
- KNN-Vektorindexe erstellen und verwalten
- Erstellen Sie eine KNN-Abfrage (K-Nearest-Nachbar) mit einem der unterstützten Vektoren. Entfernungsfunktionen
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 eine Vektoreinbettung in einer Firestore-Dokument:
Python
from google.cloud import firestore from google.cloud.firestore_v1.vector import Vector firestore_client = firestore.Client() 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
Um Vektoreinbettungen zu berechnen und zu speichern, wenn ein Dokument aktualisiert oder können Sie eine Cloud Run-Funktion einrichten:
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 Sie Vektorindexe erstellen und verwalten.
Vektorindex erstellen
Um einen Vektorindex zu erstellen, verwenden Sie
gcloud alpha firestore indexes composite create
:
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": "{}"}
.
Im folgenden Beispiel wird ein zusammengesetzter Index erstellt, einschließlich eines Vektorindex für das Feld vector-field
und einen aufsteigenden Index für das Feld color
. Sie können diese Art von Index verwenden, um vorzufiltern
Daten vor der Suche nach dem nächsten Nachbarn.
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=vector-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.
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
zum Abrufen der Index-ID. - database-id ist die ID der Datenbank.
Abfrage für den nächsten Nachbarn stellen
Sie können eine Ähnlichkeitssuche durchführen, um die nächsten Nachbarn eines Vektoreinbettung. Für Ähnlichkeitssuchen sind Vektorindexe erforderlich. Wenn kein Index vorhanden ist, schlägt Firestore einen zu erstellenden Index vor. über die gcloud CLI.
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
Abfragen für nächste Nachbarn unterstützen die folgenden Optionen für die Vektorentfernung:
EUCLIDEAN
: Misst die EUCLIDEAN-Abstand zwischen den Vektoren. Weitere Informationen finden Sie unter Euklidisch.COSINE
: vergleicht Vektoren anhand des Winkels zwischen ihnen. eine Ähnlichkeit zu messen, die nicht auf der Größe der Vektoren basiert. Wir empfehlen die Verwendung vonDOT_PRODUCT
mit standardisierten Einheitsvektoren anstelle von COSINE-Distanz, der mathematisch äquivalent mit einer besseren die Leistung. Weitere Informationen finden Sie unter Informationen zur Kosinus-Ähnlichkeit mehr.DOT_PRODUCT
: Ähnlich wieCOSINE
, wird aber durch die Größe des Vektoren. Weitere Informationen finden Sie unter Punktprodukt:
Daten vorfiltern
Um Daten vor der Suche nach den nächsten Nachbarn vorzufiltern, können Sie
mit anderen Filtern außer Ungleichheitsfiltern aus. Die and
und
or
zusammengesetzte Filter werden unterstützt. Für Feldfilter gilt Folgendes:
-Filter werden 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 beträgt 2.048. Verwenden Sie zum Speichern größerer Indexe Dimensionsreduzierung.
- Die maximale Anzahl von Dokumenten, die von einer Abfrage des nächsten Nachbarn zurückgegeben werden soll, beträgt 1.000.
- Die Vektorsuche unterstützt keine Echtzeit-Snapshot-Listener.
- Die Vektorsuche wird nur von den Python- und Node.js-Clientbibliotheken unterstützt.