На странице показано, как использовать Cloud Firestore для поиска векторов K-ближайшего соседа (KNN), используя следующие методы:
- Сохранение векторных значений
- Создание векторных индексов KNN и управление ими
- Создайте запрос K-ближайшего соседа (KNN), используя одну из поддерживаемых функций векторного расстояния.
Сохранение векторных вложений
Вы можете создавать векторные значения, такие как встраивание текста , из данных Cloud Firestore и хранить их в документах Cloud Firestore.
Операция записи с векторным вложением
В следующем примере показано, как сохранить векторное внедрение в документ Cloud Firestore:
Питон
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]) });
Вычисление векторных вложений с помощью облачной функции
Чтобы вычислять и сохранять векторные внедрения при каждом обновлении или создании документа, вы можете настроить облачную функцию :
Питон
@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 — это идентификатор группы коллекций.
- vector-field — это имя поля, которое содержит вложение вектора.
- database-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 на идентификатор базы данных.
Удаление векторного индекса
gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
где:
- index-id — это идентификатор индекса, который нужно удалить. Используйте
indexes composite list
для получения идентификатора индекса. - database-id — это идентификатор базы данных.
Описать векторный индекс
gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
где:
- index-id — это идентификатор описываемого индекса. Используйте или
indexes composite list
для получения идентификатора индекса. - database-id — это идентификатор базы данных.
Сделать запрос ближайшего соседа
Вы можете выполнить поиск по сходству, чтобы найти ближайших соседей векторного вложения. Для поиска по сходству требуются векторные индексы . Если индекс не существует, Cloud Firestore предлагает создать индекс с помощью интерфейса командной строки gcloud.
Питон
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
: Измеряет ЕВКЛИДОВОЕ расстояние между векторами. Чтобы узнать больше, см. Евклид . -
COSINE
: сравнивает векторы по углу между ними, что позволяет измерить сходство, не основанное на величине векторов. Мы рекомендуем использоватьDOT_PRODUCT
с единичными нормализованными векторами вместо расстояния COSINE, что математически эквивалентно и обеспечивает лучшую производительность. Чтобы узнать больше, см. Сходство косинуса , чтобы узнать больше. -
DOT_PRODUCT
: аналогичноCOSINE
, но на него влияет величина векторов. Дополнительные сведения см. в разделе Скалярное произведение .
Данные предварительной фильтрации
Чтобы предварительно отфильтровать данные перед поиском ближайших соседей, вы можете объединить поиск по сходству с другими фильтрами, кроме фильтров неравенства. Поддерживаются составные фильтры and
и or
. Для фильтров полей поддерживаются следующие фильтры:
-
==
равно -
in
-
array_contains
-
array_contains_any
Питон
# 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. Для хранения индексов большего размера используйте уменьшение размерности .
- Максимальное количество документов, возвращаемых по запросу ближайшего соседа, — 1000.
- Векторный поиск не поддерживает прослушиватели снимков в реальном времени .
- Вы не можете использовать фильтры неравенства для предварительной фильтрации данных.
- Только клиентские библиотеки Python и Node.js поддерживают векторный поиск.
Что дальше
- Прочтите о лучших методах работы с Cloud Firestore.
- Понимание операций чтения и записи в масштабе