Cerca con incorporamenti vettoriali
La pagina mostra come utilizzare Firestore per eseguire la query K-più vicina le ricerche di vettori di vicini (KNN) utilizzando le seguenti tecniche:
- Archivia i valori dei vettori
- Crea e gestisci indici vettoriali KNN
- Esegui una query K-Neighbor (KNN) utilizzando uno dei vettori supportati funzioni di distanza
Archivia gli incorporamenti vettoriali
Puoi creare valori vettoriali come gli incorporamenti di testo dal tuo Firestore e archiviali in documenti Firestore.
Operazione di scrittura con un incorporamento vettoriale
L'esempio seguente mostra come archiviare un incorporamento vettoriale in un Documento Firestore:
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]) });
Calcola gli incorporamenti vettoriali con una Cloud Function
Per calcolare e archiviare gli incorporamenti vettoriali ogni volta che un documento viene aggiornato puoi configurare una funzione Cloud Functions:
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, }); }
Crea e gestisci indici vettoriali
Prima di poter eseguire una ricerca per il vicino più prossimo con gli incorporamenti vettoriali, devi creare un indice corrispondente. I seguenti esempi dimostrano come creare e gestire gli indici vettoriali.
Crea un indice vettoriale
Per creare un indice vettoriale, utilizza
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
dove:
- collection-group è l'ID del gruppo di raccolte.
- vector-field è il nome del campo che contiene l'incorporamento vettoriale.
- database-id è l'ID del database.
- vector-configuration include il vettore
dimension
e il tipo di indice.dimension
è un numero intero fino a 2048. Il tipo di indice deve essereflat
. Formatta la configurazione dell'indice come segue:{"dimension":"DIMENSION", "flat": "{}"}
.
L'esempio seguente crea un indice composto, incluso un indice vettoriale per il campo vector-field
e un indice crescente per il campo color
. Puoi utilizzare questo tipo di indice per pre-filtrare
dati prima della ricerca del vicino più prossimo.
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
Elenca tutti gli indici vettoriali
gcloud
gcloud alpha firestore indexes composite list --database=database-id
Sostituisci database-id con l'ID del database.
Eliminare un indice vettoriale
gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
dove:
- index-id è l'ID dell'indice da eliminare.
Utilizza
indexes composite list
per recuperare l'ID indice. - database-id è l'ID del database.
Descrivere un indice vettoriale
gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
dove:
- index-id è l'ID dell'indice da descrivere. Utilizza o
indexes composite list
per recuperare l'ID indice. - database-id è l'ID del database.
Eseguire una query per il vicino più prossimo
Puoi eseguire una ricerca di somiglianza per trovare i vicini più prossimi di una all'incorporamento vettoriale. Le ricerche di analogie richiedono indici vettoriali. Se non esiste un indice, Firestore suggerisce un indice da creare utilizzando 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();
Distanze vettoriali
Le query per il vicino più vicino supportano le seguenti opzioni per la distanza vettoriale:
EUCLIDEAN
: misura la distanza EUCLIDEAN tra i vettori. Per saperne di più, vedi Euclidea.COSINE
: confronta i vettori in base all'angolo tra di loro, consentendoti di misurare la somiglianza che non si basa sulla grandezza del vettore. Ti consigliamo di utilizzareDOT_PRODUCT
con vettori normalizzati dell'unità anziché la distanza COSINE, che è matematicamente equivalente con una delle prestazioni. Per saperne di più, vedi Somiglianza della coseno da imparare altro ancora.DOT_PRODUCT
: simile aCOSINE
, ma è influenzata dalla grandezza della vettori di rete. Per saperne di più, vedi Prodotto Dot.
Dati prefiltro
Per prefiltrare i dati prima di trovare i vicini più prossimi, puoi combinare una
ricerca di somiglianze con altri filtri, ad eccezione dei filtri di disuguaglianze. Le and
e
Sono supportati or
filtri compositi. Per i filtri di campo, quanto segue
sono supportati i seguenti filtri:
==
uguale ain
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();
Limitazioni
Quando lavori con gli incorporamenti vettoriali, tieni presente le seguenti limitazioni:
- La dimensione di incorporamento massima supportata è 2048. Per archiviare indici più grandi, utilizza riduzione della dimensionalità.
- Il numero massimo di documenti da restituire da una query al vicino più prossimo è 1000.
- La ricerca vettoriale non supporta i listener di snapshot in tempo reale.
- Non puoi utilizzare i filtri di disuguaglianze per prefiltrare i dati.
- Solo le librerie client Python e Node.js supportano la ricerca vettoriale.
Passaggi successivi
- Leggi le best practice per Firestore.
- Comprendere le letture e le scritture su larga scala