Поиск с векторными вложениями

На странице показано, как использовать 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

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": "{}"} .

Создайте составной векторный индекс

В следующем примере создается составной векторный индекс для 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=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 поддерживают векторный поиск.

Что дальше