1. Введение
В этом практическом занятии вы узнаете, как выполнять гибридный поиск в AlloyDB, используя расширение RUM (Ranking Update Method) и индекс Scalable Nearest Neighbor (ScaNN). Это занятие является частью серии практических занятий, посвященных функциям искусственного интеллекта AlloyDB. Подробнее можно узнать на странице AlloyDB AI в документации.
Предварительные требования
- Базовое понимание Google Cloud и консоли.
- Базовые навыки работы с командной строкой и оболочкой Google Sheets.
Что вы узнаете
- Как развернуть кластер AlloyDB и основной экземпляр
- Как подключиться к AlloyDB с виртуальной машины Google Compute Engine
- Как создать базу данных и включить AlloyDB AI
- Как загрузить данные в базу данных
- Как использовать AlloyDB Studio
- Создавайте векторные представления с помощью Vertex AI.
- Как создать векторный индекс ScaNN для повышения эффективности векторного поиска
- Как включить и использовать расширение RUM для полнотекстового поиска
- Выполните гибридный поиск, комбинируя полнотекстовый поиск, векторный поиск и алгоритм взаимного рангового слияния (RRF).
Что вам понадобится
- Аккаунт Google Cloud и проект Google Cloud
- Веб-браузер, например Chrome.
2. Настройка и требования
Настройка проекта
Войдите в консоль Google Cloud . Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .
Используйте личный аккаунт вместо рабочего или учебного.
Создайте проект в Google Cloud.
- В консоли Google Cloud на странице выбора проекта выберите или создайте проект Google Cloud .
- Убедитесь, что для вашего облачного проекта включена функция выставления счетов. Узнайте, как проверить, включена ли функция выставления счетов для проекта .
Включить выставление счетов
Для включения оплаты у вас есть два варианта. Вы можете использовать свой личный платежный аккаунт или обменять средства, выполнив следующие шаги.
Создайте личный платежный аккаунт.
Если вы настроили оплату с использованием кредитов Google Cloud, этот шаг можно пропустить.
Чтобы настроить личный платежный аккаунт, перейдите сюда, чтобы включить оплату в облачной консоли.
Несколько замечаний:
- Выполнение этой лабораторной работы должно обойтись менее чем в 3 доллара США в виде облачных ресурсов.
- В конце этой лабораторной работы вы можете выполнить действия по удалению ресурсов, чтобы избежать дальнейших списаний средств.
- Новые пользователи могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .
Запустить Cloud Shell
Хотя Google Cloud можно управлять удаленно с ноутбука, в этом практическом занятии вы будете использовать Google Cloud Shell — среду командной строки, работающую в облаке.
Cloud Shell — это среда командной строки, работающая в Google Cloud и поставляемая с предустановленными необходимыми инструментами.
- В верхней части консоли Google Cloud нажмите кнопку «Активировать Cloud Shell» .
- После подключения к Cloud Shell подтвердите свою аутентификацию:
gcloud auth list - Убедитесь, что ваш проект настроен:
gcloud config get project - Если параметры вашего проекта заданы не так, как ожидалось, настройте их следующим образом:
export PROJECT_ID=<YOUR_PROJECT_ID> gcloud config set project $PROJECT_ID
Эта виртуальная машина содержит все необходимые инструменты разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Вся работа в этом практическом задании может выполняться в браузере. Вам не нужно ничего устанавливать.
3. Прежде чем начать
Включить API
Выход:
Для использования AlloyDB , Compute Engine , сетевых сервисов и Vertex AI необходимо включить соответствующие API в вашем проекте Google Cloud.
Включение API
В терминале Cloud Shell убедитесь, что идентификатор вашего проекта указан правильно:
gcloud config set project [YOUR-PROJECT-ID]
Установите переменную среды PROJECT_ID:
PROJECT_ID=$(gcloud config get-value project)
Включите все необходимые API:
gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com
Ожидаемый результат
student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
Представляем API.
- API AlloyDB (
alloydb.googleapis.com) позволяет создавать, управлять и масштабировать кластеры AlloyDB для PostgreSQL. Он предоставляет полностью управляемый, совместимый с PostgreSQL сервис баз данных, разработанный для ресурсоемких корпоративных транзакционных и аналитических задач. - API Compute Engine (
compute.googleapis.com) позволяет создавать и управлять виртуальными машинами (ВМ), постоянными дисками и сетевыми настройками. Он предоставляет базовую инфраструктуру как услугу (IaaS), необходимую для запуска ваших рабочих нагрузок и размещения базовой инфраструктуры для множества управляемых сервисов. - API Cloud Resource Manager (
cloudresourcemanager.googleapis.com) позволяет программно управлять метаданными и конфигурацией вашего проекта Google Cloud. Он позволяет организовывать ресурсы, управлять политиками управления идентификацией и доступом (IAM) и проверять разрешения в иерархии проекта. - API для настройки сетевого взаимодействия сервисов (
servicenetworking.googleapis.com) позволяет автоматизировать настройку частного подключения между вашей виртуальной частной сетью (VPC) и управляемыми сервисами Google. Он необходим для установления частного IP-доступа для таких сервисов, как AlloyDB, чтобы они могли безопасно взаимодействовать с другими вашими ресурсами. - API Vertex AI (
aiplatform.googleapis.com) позволяет вашим приложениям создавать, развертывать и масштабировать модели машинного обучения. Он предоставляет единый интерфейс для всех сервисов искусственного интеллекта Google Cloud, включая доступ к моделям генеративного ИИ (например, Gemini) и обучению пользовательских моделей.
При желании вы можете настроить свой регион по умолчанию для использования моделей встраивания Vertex AI. Подробнее о доступных регионах для Vertex AI можно прочитать здесь. В примере мы используем регион us-central1.
gcloud config set compute/region us-central1
4. Развертывание AlloyDB
Перед созданием кластера AlloyDB нам необходим доступный диапазон частных IP-адресов в нашей VPC, который будет использоваться будущим экземпляром AlloyDB. Если его нет, нам нужно его создать, назначить для использования внутренними сервисами Google, после чего мы сможем создать кластер и экземпляр.
Создать частный диапазон IP-адресов
Нам необходимо настроить параметры доступа к частным сервисам (Private Service Access, VPC) в нашей VPC для AlloyDB. Предполагается, что в проекте используется «стандартная» сеть VPC, и она будет применяться для всех действий.
Создайте диапазон частных IP-адресов:
gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
Создайте частное соединение, используя выделенный диапазон IP-адресов:
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
Ожидаемый вывод в консоль:
student@cloudshell:~ (test-project-402417)$ gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/global/addresses/psa-range].
student@cloudshell:~ (test-project-402417)$ gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
Operation "operations/pssn.p24-4470404856-595e209f-19b7-4669-8a71-cbd45de8ba66" finished successfully.
student@cloudshell:~ (test-project-402417)$
Создание кластера AlloyDB
В этом разделе мы создаём кластер AlloyDB в регионе us-central1.
Задайте пароль для пользователя postgres. Вы можете задать собственный пароль или использовать функцию генерации случайных чисел.
export PGPASSWORD=`openssl rand -hex 12`
Ожидаемый вывод в консоль:
student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`
Запишите пароль от PostgreSQL для дальнейшего использования.
echo $PGPASSWORD
Этот пароль понадобится вам в будущем для подключения к экземпляру под учетной записью postgres. Я рекомендую записать его или скопировать куда-нибудь, чтобы иметь возможность использовать позже.
Ожидаемый вывод в консоль:
student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD bbefbfde7601985b0dee5723
Создание кластера AlloyDB
Определите регион и имя кластера AlloyDB. Мы будем использовать регион us-central1 и имя кластера alloydb-hybrid-search:
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
Выполните команду для создания кластера:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
Ожидаемый вывод в консоль:
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.
Создайте основной экземпляр AlloyDB для нашего кластера в той же сессии Cloud Shell. Если вы отключены, вам потребуется заново определить переменные среды для региона и имени кластера.
gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=2 \
--region=$REGION \
--cluster=$ADBCLUSTER
Ожидаемый вывод в консоль:
student@cloudshell:~ (alloydb-hybrid-search)$ gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=2 \
--region=$REGION \
--availability-type ZONAL \
--cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.
5. Подключитесь к AlloyDB
AlloyDB развертывается с использованием только частного соединения, поэтому для работы с базой данных нам необходима виртуальная машина с установленным клиентом PostgreSQL.
Развертывание виртуальной машины GCE
Создайте виртуальную машину GCE в том же регионе и VPC, что и кластер AlloyDB.
В оболочке Cloud Shell выполните:
export ZONE=us-central1-a
gcloud compute instances create instance-1 \
--zone=$ZONE \
--create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" --format="value(name)") \
--scopes=https://www.googleapis.com/auth/cloud-platform
Ожидаемый вывод в консоль:
student@cloudshell:~ (alloydb-hybrid-search)$ export ZONE=us-central1-a
student@cloudshell:~ (talloydb-hybrid-search)$ export ZONE=us-central1-a
gcloud compute instances create instance-1 \
--zone=$ZONE \
--create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" --format="value(name)") \
--scopes=https://www.googleapis.com/auth/cloud-platform
Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/zones/us-central1-a/instances/instance-1].
NAME: instance-1
ZONE: us-central1-a
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.2
EXTERNAL_IP: 34.71.192.233
STATUS: RUNNING
Установите клиент PostgreSQL.
Установите клиентское программное обеспечение PostgreSQL на развернутую виртуальную машину.
Подключитесь к виртуальной машине:
gcloud compute ssh instance-1 --zone=us-central1-a
Ожидаемый вывод в консоль:
student@cloudshell:~ (alloydb-hybrid-search)$ gcloud compute ssh instance-1 --zone=us-central1-a Updating project ssh metadata...working..Updated [https://www.googleapis.com/compute/v1/projects/alloydb-hybrid-search]. Updating project ssh metadata...done. Waiting for SSH key to propagate. Warning: Permanently added 'compute.5110295539541121102' (ECDSA) to the list of known hosts. Linux instance-1.us-central1-a.c.gleb-test-short-001-418811.internal 6.1.0-18-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. student@instance-1:~$
Установите программное обеспечение, запускаемое командой внутри виртуальной машины:
sudo apt-get update
sudo apt-get install --yes postgresql-client
Ожидаемый вывод в консоль:
student@instance-1:~$ sudo apt-get update sudo apt-get install --yes postgresql-client Get:1 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable InRelease [5146 B] Get:2 https://packages.cloud.google.com/apt cloud-sdk-bullseye InRelease [6406 B] Hit:3 https://deb.debian.org/debian bullseye InRelease Get:4 https://deb.debian.org/debian-security bullseye-security InRelease [48.4 kB] Get:5 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable/main amd64 Packages [1930 B] Get:6 https://deb.debian.org/debian bullseye-updates InRelease [44.1 kB] Get:7 https://deb.debian.org/debian bullseye-backports InRelease [49.0 kB] ...redacted... update-alternatives: using /usr/share/postgresql/13/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode Setting up postgresql-client (13+225) ... Processing triggers for man-db (2.9.4-2) ... Processing triggers for libc-bin (2.31-13+deb11u7) ...
Подключитесь к экземпляру
Подключитесь к основному экземпляру с виртуальной машины, используя psql.
В той же вкладке Cloud Shell, где открыта SSH-сессия к вашей виртуальной машине instance-1.
Используйте указанное значение пароля AlloyDB (PGPASSWORD) и идентификатор кластера AlloyDB для подключения к AlloyDB с виртуальной машины GCE:
export PGPASSWORD=<Noted password>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
export INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
psql "host=$INSTANCE_IP user=postgres sslmode=require"
Ожидаемый вывод в консоль:
student@instance-1:~$ export PGPASSWORD=CQhOi5OygD4ps6ty student@instance-1:~$ ADBCLUSTER=alloydb-aip-01 student@instance-1:~$ REGION=us-central1 student@instance-1:~$ INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)") gleb@instance-1:~$ psql "host=$INSTANCE_IP user=postgres sslmode=require" psql (15.6 (Debian 15.6-0+deb12u1), server 15.5) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. postgres=>
Закройте сессию psql:
exit
6. Подготовка базы данных
Нам необходимо создать базу данных, включить интеграцию с Vertex AI, создать объекты базы данных и импортировать данные.
Предоставьте необходимые разрешения AlloyDB
Добавьте разрешения Vertex AI для агента службы AlloyDB.
Откройте еще одну вкладку Cloud Shell, используя знак "+" вверху.

В новой вкладке облачной оболочки выполните:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
Ожидаемый вывод в консоль:
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-11039] student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \ --role="roles/aiplatform.user" Updated IAM policy for project [test-project-001-402417]. bindings: - members: - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com role: roles/aiplatform.user - members: ... etag: BwYIEbe_Z3U= version: 1
Закройте вкладку, выполнив одну из команд, указанных на вкладке, например, «Выход»:
exit
Создать базу данных
Создайте базу данных с именем quickstart.
В сессии виртуальной машины GCE выполните:
Создать базу данных:
psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db"
Ожидаемый вывод в консоль:
student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db" CREATE DATABASE student@instance-1:~$
Включите интеграцию Vertex AI
Включите интеграцию Vertex AI и расширения pgvector в базе данных.
В виртуальной машине GCE выполните:
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE"
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector"
Ожидаемый вывод в консоль:
student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE" psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector" CREATE EXTENSION CREATE EXTENSION student@instance-1:~$
Импорт данных
Загрузите подготовленные данные и импортируйте их в новую базу данных.
В виртуальной машине GCE выполните:
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header"
Ожидаемый вывод в консоль:
student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" SET SET SET SET SET set_config ------------ (1 row) SET SET SET SET SET SET CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE SEQUENCE ALTER TABLE ALTER SEQUENCE ALTER TABLE ALTER TABLE ALTER TABLE student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header" COPY 941 student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header" COPY 263861 student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header" COPY 4654 student@instance-1:~$
7. Создание векторных представлений
После импорта данных у нас есть следующие таблицы: cymbal_products , в которой хранится информация о товарах, cymbal_inventory , которая отслеживает наличие товаров в каждом магазине, и cymbal_stores , представляющая собой список магазинов. Для выполнения семантического поиска по нашим товарам нам необходимо сгенерировать векторные представления описаний товаров с помощью функции initialize_embeddings . Мы будем использовать интеграцию с Vertex AI для вычисления векторных данных на основе описаний товаров и добавления их в таблицу. Подробнее об используемой технологии можно прочитать в документации .
Для использования интеграции подключитесь к базе данных с помощью psql с вашей виртуальной машины, используя IP-адрес экземпляра AlloyDB и пароль postgres:
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
Проверьте версию расширения google_ml_integration.
SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
Версия должна быть 1.5.2 или выше. Вот пример вывода:
quickstart_db=> SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration'; extversion ------------ 1.5.2 (1 row)
По умолчанию должна быть установлена версия 1.5.2 или выше, но если в вашем экземпляре отображается более старая версия, вероятно, её необходимо обновить. Проверьте, не отключено ли техническое обслуживание для данного экземпляра.
Для повышения эффективности мы будем использовать пакетную генерацию эмбеддингов. Подробнее о различных вариантах и методах генерации эмбеддингов можно прочитать в руководстве . Для использования пакетной генерации эмбеддингов необходимо включить параметр goole_ml_integration.enable_faster_embedding_generation
show google_ml_integration.enable_faster_embedding_generation;
Если флаг находится в правильном положении, ожидаемый результат будет выглядеть следующим образом:
quickstart_db=> show google_ml_integration.enable_faster_embedding_generation; google_ml_integration.enable_faster_embedding_generation ---------------------------------------------------------- on (1 row)
Но если отображается "выключено", то нам нужно обновить экземпляр. Это можно сделать с помощью веб-консоли или команды gcloud, как описано в документации . Здесь я покажу, как это сделать с помощью команды gcloud:
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags google_ml_integration.enable_faster_embedding_generation=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
Это может занять несколько минут, но в конечном итоге значение флага должно переключиться в положение «включено». После этого вы можете перейти к следующим шагам.
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
В сессии psql, подключенной к базе данных, создайте новый столбец для хранения эмбеддингов в cymbal_products
ALTER TABLE cymbal_products ADD COLUMN product_embedding vector(768);
Ожидаемый вывод в консоль:
quickstart_db=> ALTER TABLE cymbal_products ADD COLUMN product_embedding vector(768); ALTER TABLE quickstart_db=>
Наконец, мы также хотим, чтобы эмбеддинги обновлялись по мере изменения значений столбцов, для чего необходимо включить аргумент incremental_refresh_mode в вызов функции. Это создает дополнительную нагрузку на нашу базу данных, но это компромисс, на который мы идем, чтобы автоматически синхронизировать эмбеддинги с контентом. Если вы хотите обновлять эмбеддинги вручную, инструкции можно найти в документации .
Теперь, чтобы собрать все воедино и сгенерировать эмбеддинги, мы используем функцию initialize_embeddings , передаем batch_size равный 50 в качестве параметра batch_signal и устанавливаем incremental_refresh_mode в transactional
CALL ai.initialize_embeddings(
model_id => 'text-embedding-005',
table_name => 'cymbal_products',
content_column => 'product_description',
embedding_column => 'product_embedding',
batch_size => 50,
incremental_refresh_mode => 'transactional'
);
А теперь, если мы вставим в таблицу новую строку со значением NULL для столбца product_embedding
INSERT INTO "cymbal_products" ("uniq_id", "crawl_timestamp", "product_url", "product_name", "product_description", "list_price", "sale_price", "brand", "item_number", "gtin", "package_size", "category", "postal_code", "available", "product_embedding") VALUES ('fd604542e04b470f9e6348e640cff794', NOW(), 'https://example.com/new_product', 'New Cymbal Product', 'This is a new cymbal product description.', 199.99, 149.99, 'Example Brand', 'EB123', '1234567890', 'Single', 'Cymbals', '12345', TRUE, NULL);
Теперь, когда мы выполним запрос к только что вставленной строке, мы увидим, что столбец product_embedding автоматически обновится.
SELECT uniq_id, (product_embedding::real[])[1:5] as product_embedding FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';
Результат должен выглядеть следующим образом:
quickstart_db=> SELECT uniq_id,(product_embedding::real[])[1:5] as product_embedding FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';
uniq_id | product_embedding
----------------------------------+---------------------------------------------------------------
fd604542e04b470f9e6348e640cff794 | {0.015003494,-0.005349732,-0.059790313,-0.0087091,-0.0271452}
(1 row)
Time: 3.295 ms
8. Создать векторный индекс
Для повышения эффективности векторного поиска мы добавим индекс ScaNN .
Создать индекс ScaNN
Для построения индекса SCANN нам необходимо включить еще одно расширение. Расширение alloydb_scann предоставляет интерфейс для работы с векторным индексом типа ANN, использующим алгоритм ScaNN от Google.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
Ожидаемый результат:
quickstart_db=> CREATE EXTENSION IF NOT EXISTS alloydb_scann; CREATE EXTENSION Time: 27.468 ms quickstart_db=>
Индекс можно создать в ручном (MANUAL) или автоматическом (AUTO) режиме. Ручной режим включен по умолчанию, и вы можете создать индекс и поддерживать его так же, как и любой другой индекс. Но если вы включите автоматический режим, вы сможете создать индекс, который не потребует от вас никакого обслуживания. Подробно обо всех параметрах можно прочитать в документации . В нашем случае у нас недостаточно строк для создания индекса в автоматическом режиме, поэтому мы создадим его в ручном режиме и добавим параметры настройки. О настройке параметров индекса можно прочитать в документации .
Для изменения параметров настройки необходимо включить флаг scann.enable_preview_features . Это можно сделать в Cloudshell.
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags scann.enable_preview_features=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
Это может занять несколько минут, но в конечном итоге значение флага должно быть установлено в положение «включено». После установки флага мы можем вернуться к нашей сессии psql на виртуальной машине и создать индекс с параметрами настройки.
CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products
USING scann (product_embedding cosine)
WITH (mode='MANUAL', num_leaves=31, max_num_levels = 2);
Ожидаемый результат:
quickstart_db=> CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products USING scann (product_embedding cosine) WITH (num_leaves=31, max_num_levels = 2); CREATE INDEX quickstart_db=>
Проверьте использование индекса
Теперь мы можем выполнить запрос векторного поиска в режиме EXPLAIN и проверить, используется ли индекс.
EXPLAIN (analyze)
WITH trees as (
SELECT
cp.product_name,
left(cp.product_description,80) as description,
cp.sale_price,
cs.zip_code,
cp.uniq_id as product_id
FROM
cymbal_products cp
JOIN cymbal_inventory ci on
ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
cs.store_id=ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
(cp.product_embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;
Ожидаемый результат (отредактировано для ясности):
... Aggregate (cost=16.59..16.60 rows=1 width=32) (actual time=2.875..2.877 rows=1 loops=1) -> Subquery Scan on trees (cost=8.42..16.59 rows=1 width=142) (actual time=2.860..2.862 rows=1 loops=1) -> Limit (cost=8.42..16.58 rows=1 width=158) (actual time=2.855..2.856 rows=1 loops=1) -> Nested Loop (cost=8.42..6489.19 rows=794 width=158) (actual time=2.854..2.855 rows=1 loops=1) -> Nested Loop (cost=8.13..6466.99 rows=794 width=938) (actual time=2.742..2.743 rows=1 loops=1) -> Index Scan using cymbal_products_embeddings_scann on cymbal_products cp (cost=7.71..111.99 rows=876 width=934) (actual time=2.724..2.724 rows=1 loops=1) Order By: (embedding <=> '[0.008864171,0.03693164,-0.024245683,-0.00355923,0.0055611245,0.015985578,...<redacted>...5685,-0.03914233,-0.018452475,0.00826032,-0.07372604]'::vector) ...
Из выходных данных ясно видно, что запрос использовал "Index Scan using cymbal_products_embeddings_scann on cymbal_products".
9. Индекс полнотекстового поиска
AlloyDB поддерживает все типы индексов для полнотекстового поиска, которые поддерживаются в PostgreSQL. Выбор индекса зависит от баланса между скоростью поиска, временем построения индекса, скоростью обновления и необходимыми функциями поиска, такими как поиск по фразам или ранжирование по релевантности.
В нашем примере мы будем использовать расширение RUM для повышения производительности операций полнотекстового поиска. RUM улучшает стандартные индексы GIN, сохраняя позиционную информацию непосредственно в индексе, что позволяет выполнять более быстрый поиск по фразам и ранжирование по релевантности без доступа к данным таблицы.
Для включения расширения Rum вы можете использовать AlloyDB Studio или продолжить использовать клиент psql
Создать индекс RUM
CREATE EXTENSION IF NOT EXISTS rum;
Для поиска по описаниям товаров в таблице cymbal_products необходимо создать столбец, который будет хранить описание товара в формате tsvector . Этот столбец автоматически сохраняет обработанный текст и повышает производительность запросов.
ALTER TABLE cymbal_products
ADD COLUMN product_search_vector tsvector
GENERATED ALWAYS AS (to_tsvector('english', product_description)) STORED;
Теперь мы можем создать новый RUM-индекс для столбца product_search_vector .
CREATE INDEX cymbal_products_rum
ON cymbal_products
USING rum (product_search_vector rum_tsvector_ops);
Для выполнения запроса к таблице с использованием индекса выполните следующий запрос, который ищет совпадения по запросу "cherry tree". Оператор <=> вычисляет показатель релевантности, или расстояние, между документом и запросом непосредственно из индекса.
SELECT product_name, product_description
FROM cymbal_products
WHERE product_search_vector @@ to_tsquery('english', 'cherry <-> tree')
ORDER BY product_search_vector <=> to_tsquery('english', 'cherry <-> tree');
10. Выполните гибридный поиск.
Функция google_vector_utils.hybrid_search() позволяет объединять результаты нескольких типов поиска, таких как векторный поиск и полнотекстовый поиск. Функция объединяет ранжированные результаты каждого компонента поиска в единый унифицированный список с использованием алгоритма взаимного ранжирования (RRF). Такой подход обеспечивает более релевантные результаты, чем поиск только одного типа.
Функция hybrid_search() динамически формирует и выполняет один SQL-запрос. Она создает общее табличное выражение (CTE) для каждого определенного вами компонента поиска. Затем функция объединяет результаты из всех CTE и вычисляет итоговый показатель RRF для каждого документа, чтобы получить единый ранжированный список.
Для использования этой функции необходимо включить параметр enable_preview_ai_functions в основном экземпляре. Выполните следующую команду в Cloudshell.
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags google_ml_integration.enable_preview_ai_functions=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
Следующий запрос объединяет наш предыдущий вопрос векторного поиска с вопросом полнотекстового поиска. Это очень простой гибридный поисковый запрос; вы можете попробовать что-то более сложное, например, использовать «деревья, которые растут выше дома» в компоненте векторного поиска и «Калифорния» в компоненте полнотекстового поиска.
SELECT score, id, p.product_name
FROM ai.hybrid_search(
search_inputs => ARRAY[
'{
"data_type": "vector",
"table_name": "cymbal_products",
"key_column": "uniq_id",
"vec_column": "product_embedding",
"distance_operator": "public.<=>",
"limit": 5,
"query_vector": "ai.embedding(''text-embedding-005'', ''cherry'')::vector"
}'::JSONB,
'{
"data_type": "text",
"table_name": "cymbal_products",
"key_column": "uniq_id",
"text_column": "product_search_vector",
"limit": 5,
"ranking_function": "<=>",
"query_text_input": "tree"
}'::JSONB
]
) JOIN cymbal_products p ON id = p.uniq_id;
Ожидаемый результат
"score","id","product_name" "0.00819672631147241","d536e9e823296a2eba198e52dd23e712","Cherry Tree" "0.015873015873015872","23e41a71d63d8bbc9bdfa1d118cfddc5","Apple Tree" "0.00819672631147241","dc789a2f87b142e94e6e325689482af9","Oak Tree" "0.008064521129029258","f5c70d62ccf3118d73863bf3b17edcbe","Cypress Tree" "0.008064521129029258","b70c44b1a38c0a2329fa583c9109a80f","Peach Tree"
В результатах вы найдете id который является указанным key_column , score — это итоговое значение, вычисленное алгоритмом RRF. Алгоритм Reciprocal Rank Fusion (RRF) — это алгоритм, основанный на ранжировании, который объединяет несколько ранжированных списков результатов поиска в один ранжированный список, присваивая каждому документу оценку. Эта оценка основана на обратном ранге RRF по всем участвующим спискам, при этом документы с более высоким рангом получают больший вклад. Если в параметре include_json_output => true , будет возвращен столбец detail_json , содержащий подробную информацию о вычислении оценки для каждого компонента.
В то время как полнотекстовый поиск лучше всего подходит для поиска конкретных терминов или точных совпадений, векторный поиск превосходно справляется с поиском синонимов и определением смысла даже в тех случаях, когда слова не совпадают. Объединяя эти два метода, гибридный поиск гарантирует пользователям получение надежного набора результатов, которые являются одновременно точными по смыслу и семантически релевантными.
11. Очистка окружающей среды
После завершения лабораторной работы удалите экземпляры AlloyDB и кластер.
Удалите кластер AlloyDB и все его экземпляры.
Если вы использовали пробную версию AlloyDB, не удаляйте пробный кластер, если планируете тестировать другие тестовые среды и ресурсы с его помощью. Вы не сможете создать другой пробный кластер в том же проекте.
Кластер уничтожается с помощью опции force, которая также удаляет все экземпляры, принадлежащие кластеру.
В облачной оболочке укажите переменные проекта и среды на случай, если соединение было разорвано и все предыдущие настройки были потеряны:
gcloud config set project <your project id>
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
export PROJECT_ID=$(gcloud config get-value project)
Удалите кластер:
gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
Ожидаемый вывод в консоль:
student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force All of the cluster data will be lost when the cluster is deleted. Do you want to continue (Y/n)? Y Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f Deleting cluster...done.
Удалить резервные копии AlloyDB
Удалите все резервные копии AlloyDB для кластера:
for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
Ожидаемый вывод в консоль:
student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f Deleting backup...done.
Теперь мы можем уничтожить нашу виртуальную машину.
Удалить виртуальную машину GCE
В оболочке Cloud Shell выполните:
export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
--zone=$ZONE \
--quiet
Ожидаемый вывод в консоль:
student@cloudshell:~ (test-project-001-402417)$ export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
--zone=$ZONE \
--quiet
Deleted
12. Поздравляем!
Поздравляем с завершением практического занятия!
Что мы рассмотрели
- Как развернуть кластер AlloyDB и основной экземпляр
- Как подключиться к AlloyDB с виртуальной машины Google Compute Engine
- Как создать базу данных и включить AlloyDB AI
- Как загрузить данные в базу данных
- Как использовать AlloyDB Studio
- Создавайте векторные представления с помощью Vertex AI.
- Как создать векторный индекс ScaNN для повышения эффективности векторного поиска
- Как включить и использовать расширение RUM для полнотекстового поиска
- Выполните гибридный поиск, комбинируя полнотекстовый поиск, векторный поиск и алгоритм взаимного рангового слияния (RRF).