Strona pokazuje, jak używać funkcji Cloud Firestore do wykonywania operacji K w najbliższym czasie wyszukiwanie wektorów sąsiada (KNN) przy użyciu następujących metod:
- Zapisz wartości wektorów
- Tworzenie indeksów wektorów KNN i zarządzanie nimi
- Utwórz zapytanie KNN (k-najbliższy sąsiad) przy użyciu jednego z obsługiwanych wektorów funkcje odległości
Wektory dystrybucyjne sklepów
Możesz tworzyć wartości wektorowe, takie jak wektory dystrybucyjne tekstu Cloud Firestore i przechowuj je w dokumentach Cloud Firestore.
Operacja zapisu z wektorem dystrybucyjnym wektorowym
Na przykładzie poniżej pokazujemy, jak zapisać wektor dystrybucyjny w formacie Dokument Cloud 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]) });
Wektory dystrybucyjne obliczeniowe za pomocą funkcji w Cloud Functions
Aby obliczać i przechowywać wektory dystrybucyjne wektorów za każdym razem, gdy dokument jest aktualizowany lub możesz skonfigurować funkcję w 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, }); }
Tworzenie indeksów wektorów i zarządzanie nimi
Zanim będzie można przeprowadzić wyszukiwanie najbliższych sąsiadów z użyciem wektorów dystrybucyjnych wektorowych, musisz utworzyć odpowiedni indeks. Poniższe przykłady pokazują, tworzenia indeksów wektorowych i zarządzania nimi.
Utwórz indeks wektorów
Aby utworzyć indeks wektorów, użyj funkcji
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
gdzie:
- collection-group to identyfikator grupy kolekcji.
- vector-field to nazwa pola zawierającego wektor dystrybucyjny.
- database-id to identyfikator bazy danych.
- vector-configuration obejmuje wektor
dimension
i typ indeksu.dimension
jest liczbą całkowitą do 2048. Typ indeksu musi być ustawiony naflat
. Sformatuj konfigurację indeksu w ten sposób:{"dimension":"DIMENSION", "flat": "{}"}
.
Poniższy przykład tworzy indeks złożony, w tym indeks wektorów dla pola vector-field
i indeks rosnący dla pola color
. Możesz użyć tego typu indeksu do wstępnego filtrowania
dane przed wyszukiwaniem najbliższych sąsiadów.
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
Wyświetl wszystkie indeksy wektorów
gcloud
gcloud alpha firestore indexes composite list --database=database-id
Zastąp database-id identyfikatorem bazy danych.
Usuń indeks wektorów
gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
gdzie:
- index-id to identyfikator indeksu do usunięcia.
Użyj narzędzia
indexes composite list
, aby pobrać identyfikator indeksu. - database-id to identyfikator bazy danych.
Opisz indeks wektorów
gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
gdzie:
- index-id to identyfikator indeksu do opisania. Użyj lub
indexes composite list
, aby pobrać identyfikator indeksu. - database-id to identyfikator bazy danych.
Utwórz zapytanie o najbliższych sąsiadów
Możesz wyszukać podobieństwo, aby znaleźć najbliższych sąsiadów wektorów dystrybucyjnych. Wyszukiwanie podobieństw wymaga indeksów wektorów. Jeśli indeks nie istnieje, Cloud Firestore proponuje indeks do utworzenia przy użyciu funkcji 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();
Odległości wektorowe
Zapytania o najbliższy sąsiad obsługują następujące opcje odległości wektora:
EUCLIDEAN
: mierzy odległość UECLIDEAN między wektorami. Więcej informacji: Euklidesowa.COSINE
: porównuje wektory na podstawie kąta między nimi, co pozwala mierz podobieństwo, które nie jest oparte na wielkości wektorów. Zalecamy używanie funkcjiDOT_PRODUCT
z wektorami znormalizowanymi jednostkami zamiast Odległość COSINE, która jest matematycznym odpowiednikiem z lepszym skuteczność reklam. Aby dowiedzieć się więcej, zobacz Podobieństwo cosinusowe, które ma być potrzebne i innych.DOT_PRODUCT
: podobny doCOSINE
, ale podlega wektory dystrybucyjne. Więcej informacji: Iloczyn skalarny.
Wstępnie filtruj dane
Aby wstępnie przefiltrować dane przed znalezieniem najbliższych sąsiadów, możesz połączyć
wyszukiwanie podobieństw z innymi filtrami oprócz filtrów nierówności. and
i
Obsługiwane są filtry złożone or
. W przypadku filtrów pól te wartości
obsługiwane filtry:
==
równein
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();
Ograniczenia
Korzystając z wektorów dystrybucyjnych wektorowych, pamiętaj o następujących ograniczeniach:
- Maksymalny obsługiwany wymiar wektora dystrybucyjnego to 2048. Aby przechowywać większe indeksy, użyj funkcji redukcja wymiarów.
- Maksymalna liczba dokumentów do zwrócenia z zapytania o najbliższych sąsiadów to 1000.
- Wyszukiwanie wektorowe nie obsługuje detektorów zrzutów w czasie rzeczywistym.
- Tylko biblioteki klienta Python i Node.js obsługują wyszukiwanie wektorowe.
Co dalej?
- Zapoznaj się ze sprawdzonymi metodami dotyczącymi domeny Cloud Firestore.
- Dowiedz się, jak czytać i pisać na dużą skalę.