Vektör yerleştirmeleriyle arama

Sayfada, aşağıdaki teknikleri kullanarak K en yakın komşu (KNN) vektör aramaları yapmak için Cloud Firestore'un nasıl kullanılacağı gösterilmektedir:

  • Vektör değerlerini depola
  • KNN vektör dizinlerini oluşturma ve yönetme
  • Desteklenen vektör mesafe işlevlerinden birini kullanarak K-en yakın-komşu (KNN) sorgusu yapma

Vektör yerleştirmeleri depolama

Cloud Firestore verilerinizden metin yerleştirmeler gibi vektör değerleri oluşturabilir ve bunları Cloud Firestore belgelerinde saklayabilirsiniz.

Vektör yerleştirmeyi içeren yazma işlemi

Aşağıdaki örnek, Cloud Firestore belgesine yerleştirilen bir vektörün nasıl depolanacağını gösterir:

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])
});
    

Cloud Functions işleviyle vektör yerleştirmeleri hesaplayın

Bir belge güncellendiğinde veya oluşturulduğunda vektör yerleştirmeleri hesaplamak ve depolamak için bir Cloud Functions işlevi kurabilirsiniz:

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,
  });
}
    

Vektör dizinleri oluşturma ve yönetme

Vektör yerleştirmelerinizle en yakın komşu araması yapabilmeniz için önce buna karşılık gelen bir dizin oluşturmanız gerekir. Aşağıdaki örnekler, vektör dizinlerinin nasıl oluşturulacağını ve yönetileceğini göstermektedir.

Tek alanlı vektör dizini oluşturma

Tek alanlı vektör dizini oluşturmak için gcloud alpha firestore indexes composite create işlevini kullanın:

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
    

Bu örnekte:

  • collection-group, koleksiyon grubunun kimliğidir.
  • vector-field, vektör yerleştirmeyi içeren alanın adıdır.
  • database-id, veritabanının kimliğidir.
  • vector-configuration, dimension vektörünü ve dizin türünü içeriyor. dimension, 2048'e kadar olan bir tam sayıdır. Dizin türü flat olmalıdır. Dizin yapılandırmasını şu şekilde biçimlendirin: {"dimension":"DIMENSION", "flat": "{}"}.

Bileşik vektör dizini oluşturma

Aşağıdaki örnek, color alanı ve bir vektör yerleştirme alanı için bir bileşik vektör dizini oluşturur.

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
    

Tüm vektör dizinlerini listeleme

gcloud
gcloud alpha firestore indexes composite list --database=database-id

database-id değerini veritabanının kimliğiyle değiştirin.

Vektör dizinini silme

gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
    

Bu örnekte:

  • index-id, silinecek dizinin kimliğidir. Dizin kimliğini almak için indexes composite list işlevini kullanın.
  • database-id, veritabanının kimliğidir.

Vektör endeksini açıklama

gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
    

Bu örnekte:

  • index-id, açıklanacak dizin kimliğidir. Dizin kimliğini almak için veya indexes composite list öğesini kullanın.
  • database-id, veritabanının kimliğidir.

En yakın komşu sorgusu oluşturma

Vektör yerleştirmenin en yakın komşularını bulmak için benzerlik araması yapabilirsiniz. Benzerlik aramaları için vektör dizinleri gerekir. Dizin mevcut değilse Cloud Firestore, gCloud CLI kullanılarak oluşturulacak bir dizin önerir.

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();
    

Vektör mesafeleri

En yakın komşu sorgular, vektör mesafesi için aşağıdaki seçenekleri destekler:

  • EUCLIDEAN: Vektörler arasındaki EUCLIDEAN mesafesini ölçer. Daha fazla bilgi edinmek için Öklid bölümünü inceleyin.
  • COSINE: Vektörleri aralarındaki açıya göre karşılaştırır. Bu sayede, vektörlerin büyüklüğüne bağlı olmayan benzerliği ölçebilirsiniz. Daha iyi performans gösteren ve matematiksel açıdan eşdeğer olan COSINE mesafesi yerine birim normalleştirilmiş vektörlerle DOT_PRODUCT kullanmanızı öneririz. Daha fazla bilgi için Kosinüs benzerliği bölümüne bakın.
  • DOT_PRODUCT: COSINE özelliğine benzer, ancak vektörlerin büyüklüğünden etkilenir. Daha fazla bilgi için Nokta çarpımı bölümüne bakın.

Verileri ön filtrele

En yakın komşuları bulmadan önce verileri önceden filtrelemek için benzerlik aramasını eşitsizlik filtreleri hariç diğer filtrelerle birleştirebilirsiniz. and ve or bileşik filtreler desteklenir. Alan filtreleri için aşağıdaki filtreler desteklenir:

  • == eşittir
  • in
  • 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();
    

Sınırlamalar

Vektör yerleştirmeleriyle çalışırken aşağıdaki sınırlamaları göz önünde bulundurun:

  • En fazla desteklenen yerleştirme boyutu 2048'dir. Daha büyük dizinleri depolamak için boyutluluk azaltma özelliğini kullanın.
  • En yakın komşu sorgudan döndürülecek maksimum doküman sayısı 1.000'dir.
  • Vektör arama, gerçek zamanlı anlık görüntü işleyicileri desteklemez.
  • Verileri önceden filtrelemek için eşitsizlik filtrelerini kullanamazsınız.
  • Vektör aramasını yalnızca Python ve Node.js istemci kitaplıkları destekler.

Sırada ne var?