이 페이지에서는 Cloud Firestore를 사용하여 다음 기법을 사용하여 K-최근접 이웃(KNN) 벡터 검색을 수행하는 방법을 보여줍니다.
- 벡터 값 저장
- KNN 벡터 색인 만들기 및 관리
- 지원되는 벡터 거리 함수 중 하나를 사용하여 K-최근접 이웃(KNN) 쿼리 수행
벡터 임베딩 저장
Cloud Firestore 데이터에서 텍스트 임베딩과 같은 벡터 값을 만들고 Cloud Firestore 문서에 저장할 수 있습니다.
벡터 임베딩을 사용한 쓰기 작업
다음 예시는 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]) });
Cloud 함수로 벡터 임베딩 계산
문서가 업데이트 또는 생성될 때마다 벡터 임베딩을 계산하고 저장하기 위해 Cloud 함수를 설정할 수 있습니다.
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, }); }
벡터 색인 만들기 및 관리
벡터 임베딩으로 최근접 이웃 검색을 수행하려면 먼저 해당하는 색인을 만들어야 합니다 다음 예시는 벡터 색인을 만들고 관리하는 방법을 보여줍니다.
벡터 색인 만들기
벡터 색인을 만들려면 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
각 항목의 의미는 다음과 같습니다.
- collection-group은 컬렉션 그룹의 ID입니다.
- vector-field는 벡터 임베딩이 포함된 필드의 이름입니다.
- database-id는 데이터베이스의 ID입니다.
- vector-configuration에는
dimension
벡터와 색인 유형이 포함됩니다.dimension
은 최대 2048까지의 정수입니다. 색인 유형은flat
이어야 합니다. 색인 구성의 형식을 다음과 같이 지정합니다.{"dimension":"DIMENSION", "flat": "{}"}
다음 예시에서는 vector-field
필드의 벡터 색인과 color
필드의 오름차순 색인을 포함하는 복합 색인을 만듭니다. 이러한 유형의 색인을 사용하여 최근접 이웃 검색을 수행하기 전에 데이터를 사전 필터링할 수 있습니다.
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
모든 벡터 색인 나열
gcloud
gcloud alpha firestore indexes composite list --database=database-id
database-id를 데이터베이스 ID로 바꿉니다.
벡터 색인 삭제
gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
각 항목의 의미는 다음과 같습니다.
- index-id는 삭제할 색인의 ID입니다.
indexes composite list
를 사용하여 색인 ID를 검색합니다. - database-id는 데이터베이스의 ID입니다.
벡터 색인 설명
gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
각 항목의 의미는 다음과 같습니다.
- index-id는 설명할 색인의 ID입니다.
indexes composite list
를 사용하여 색인 ID를 검색합니다. - database-id는 데이터베이스의 ID입니다.
최근접 이웃 쿼리 수행
유사성 검색을 수행하여 벡터 임베딩의 최근접 이웃을 찾을 수 있습니다. 유사성 검색에는 벡터 색인이 필요합니다. 색인이 없으면 Cloud Firestore에서 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();
벡터 거리
최근접 이웃 쿼리는 벡터 거리에 대한 다음 옵션을 지원합니다.
EUCLIDEAN
: 벡터 사이의 EUCLIDEAN 거리를 측정합니다. 자세한 내용은 유클리드를 참조하세요.COSINE
: 벡터 크기를 기반으로 하지 않는 유사성을 측정할 수 있도록 벡터 사이의 각도를 기준으로 벡터를 비교합니다. COSINE 거리 대신DOT_PRODUCT
를 단위 정규화된 벡터와 함께 사용하는 것이 좋습니다. 이는 수학적으로 동일하며 성능이 더 우수합니다. 자세한 내용은 코사인 유사성을 참조하세요.DOT_PRODUCT
:COSINE
과 유사하지만 벡터의 크기에 영향을 받습니다. 자세한 내용은 내적을 참조하세요.
데이터 사전 필터링
최근접 이웃을 찾기 전에 데이터를 사전 필터링하려면 불일치 필터를 제외한 다른 필터와의 유사성 검색을 결합할 수 있습니다. and
및 or
복합 필터가 지원됩니다. 필드 필터의 경우 다음과 같은 필터가 지원됩니다.
==
같음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();
제한사항
벡터 임베딩으로 작업할 때 다음 제한사항에 유의하세요.
- 지원되는 최대 임베딩 차원은 2048입니다. 더 큰 색인을 저장하려면 차원 축소를 사용합니다.
- 최근접 이웃 쿼리에서 반환할 최대 문서 수는 1,000개입니다.
- 벡터 검색은 실시간 스냅샷 리스너를 지원하지 않습니다.
- 불일치 필터를 사용하여 데이터를 사전 필터링할 수 없습니다.
- Python 및 Node.js 클라이언트 라이브러리만 벡터 검색을 지원합니다.
다음 단계
- Cloud Firestore 권장사항 알아보기
- 대규모 읽기 및 쓰기 이해