AlloyDB 中的多模态嵌入

1. 简介

a7e7c1d2afe05e68.png

本 Codelab 提供了有关部署 AlloyDB 并利用 AI 集成通过多模态嵌入进行语义搜索的指南。本实验是专门介绍 AlloyDB AI 功能的实验合集中的一个实验。如需了解详情,请参阅文档中的 AlloyDB AI 页面

前提条件

  • 对 Google Cloud 控制台有基本的了解
  • 具备命令行界面和 Cloud Shell 方面的基本技能

学习内容

  • 如何部署 AlloyDB for Postgres
  • 如何使用多模态矢量搜索
  • 如何启用 AlloyDB AI 运算符
  • 如何使用不同的 AlloyDB AI 运算符进行多模态搜索
  • 如何使用 AlloyDB AI 组合文本和图片搜索结果

所需条件

  • Google Cloud 账号和 Google Cloud 项目
  • 支持 Google Cloud 控制台和 Cloud Shell 的网络浏览器,例如 Chrome

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户符合参与 300 美元免费试用计划的条件。

启动 Cloud Shell

虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

Google Cloud 控制台 中,点击右上角工具栏中的 Cloud Shell 图标:

55efc1aaa7a4d3ad.png

预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:

7ffe5cbb04455448.png

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的所有工作都可以在浏览器中完成。您无需安装任何程序。

3. 准备工作

启用 API

在 Cloud Shell 中,确保项目 ID 已设置:

gcloud config set project [YOUR-PROJECT-ID]

设置环境变量 PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

启用所有必要的服务:

gcloud services enable alloydb.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com \
                       discoveryengine.googleapis.com \
                       secretmanager.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.

4. 部署 AlloyDB

创建 AlloyDB 集群和主实例。以下步骤介绍了如何使用 Google Cloud SDK 创建 AlloyDB 集群和实例。如果您偏好使用控制台方法,可以点击此处查看相关文档。

在创建 AlloyDB 集群之前,我们需要在 VPC 中分配一个可用的专用 IP 范围,以供未来的 AlloyDB 实例使用。如果我们没有该服务账号,则需要创建该服务账号,并将其分配给内部 Google 服务使用,之后我们才能创建集群和实例。

创建专用 IP 范围

我们需要在 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 集群

在本部分中,我们将在 us-central1 区域中创建一个 AlloyDB 集群。

为 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-aip-01 作为集群名称:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01

运行命令以创建集群:

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION \
    --subscription-type=TRIAL

预期的控制台输出:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION \
    --subscription-type=TRIAL
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.                                                                                                                                                                                                                                                           

在同一 Cloud Shell 会话中为集群创建 AlloyDB 主实例。如果您断开连接,则需要再次定义区域和集群名称环境变量。

gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=8 \
    --region=$REGION \
    --cluster=$ADBCLUSTER

预期的控制台输出:

student@cloudshell:~ (test-project-402417)$ gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=8 \
    --region=$REGION \
    --availability-type ZONAL \
    --cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.                                                                                                                                                                                                                                                     

创建 AlloyDB Standard 集群

如果这不是您在项目中创建的第一个 AlloyDB 集群,请继续创建标准集群。

定义区域和 AlloyDB 集群名称。我们将使用 us-central1 区域,并将 alloydb-aip-01 作为集群名称:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01

运行命令以创建集群:

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION

预期的控制台输出:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION 
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.                                                                                                                                                                                                                                                           

在同一 Cloud Shell 会话中为集群创建 AlloyDB 主实例。如果您断开连接,则需要再次定义区域和集群名称环境变量。

gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=2 \
    --region=$REGION \
    --cluster=$ADBCLUSTER

预期的控制台输出:

student@cloudshell:~ (test-project-402417)$ 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. 准备数据库

我们需要创建数据库、启用 Vertex AI 集成、创建数据库对象并导入数据。

向 AlloyDB 授予必要权限

向 AlloyDB 服务代理添加 Vertex AI 权限。

使用顶部的“+”号打开另一个 Cloud Shell 标签页。

4ca978f5142bb6ce.png

在新的 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”,关闭该标签页:

exit

连接到 AlloyDB Studio

在后续章节中,所有需要连接到数据库的 SQL 命令都可以通过 AlloyDB Studio 执行。如需运行该命令,您需要点击主实例,打开 AlloyDB 集群的 Web 控制台界面。

ef4bfbcf0ed2ef3a.png

然后点击左侧的 AlloyDB Studio:

5c155cbcd7d43a1.png

选择 postgres 数据库、用户 postgres,并提供我们在创建集群时记下的密码。然后点击“验证”按钮。

1c9dab73c6836798.png

系统会打开 AlloyDB Studio 界面。如需在数据库中运行命令,请点击右侧的“编辑器 1”标签页。

b36c28f8165119ca.png

系统会打开一个界面,您可以在其中运行 SQL 命令

cf43aa20f292797e.png

创建数据库

创建数据库快速入门。

在 AlloyDB Studio 编辑器中,执行以下命令。

创建数据库:

CREATE DATABASE quickstart_db

预期输出:

Statement executed successfully

连接到 quickstart_db

使用切换用户/数据库按钮重新连接到工作室。

e826ad973eb23a74.png

从下拉列表中选择新的 quickstart_db 数据库,并使用与之前相同的用户和密码。

1ca70c59b5aea8c1.png

系统将打开一个新连接,您可以在其中处理 quickstart_db 数据库中的对象。

6. 示例数据

现在,我们需要在数据库中创建对象并加载数据。我们将使用虚构的“Cymbal”商店和虚构的数据。

在导入数据之前,我们需要启用支持数据类型和索引的扩展程序。我们需要两个扩展程序,一个支持向量数据类型,另一个支持 AlloyDB ScaNN 索引。

在连接到 quickstart_db 的 AlloyDB Studio 中执行。

CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS alloydb_scann;

数据集已准备好并以 SQL 文件形式放置,可以使用导入界面加载到数据库中。在 Cloud Shell 中,执行以下命令:

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters import $ADBCLUSTER --region=$REGION --database=quickstart_db --gcs-uri='gs://sample-data-and-media/ecomm-retail/ecom_generic_vectors.sql' --user=postgres --sql

该命令使用 AlloyDB SDK 创建一个名为 agentspace_user 的用户,然后直接从 GCS 存储分区将示例数据导入到数据库,创建所有必需的对象并插入数据。

导入完成后,我们可以在 AlloyDB Studio 中查看表。这些表位于 ecomm 架构中:

9ee57986d4cdf20f.png

并验证其中一个表中的行数。

51c3c55881157da3.png

我们已成功导入示例数据,可以继续执行后续步骤。

7. 使用文本嵌入执行语义搜索

在本章中,我们将尝试使用文本嵌入进行语义搜索,并将其与传统的 Postgres 文本和全文搜索进行比较。

我们先尝试使用带有 LIKE 运算符的标准 PostgreSQL SQL 进行经典搜索。

如果我们尝试使用以下查询搜索雨衣:

SET session.my_search_var='%wet%conditions%jacket%';
SELECT
  name,
  product_description,
  retail_price,   replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
FROM
  ecomm.products
WHERE
  name ILIKE current_setting('session.my_search_var')
  OR product_description ILIKE current_setting('session.my_search_var')
LIMIT
  10;

由于商品名称或说明中需要包含“潮湿天气”和“夹克”等确切字词,因此该查询不会返回任何行。“潮湿条件夹克”与“雨天条件夹克”不同。

我们可以尝试在搜索中包含所有可能的变体。我们试着只包含两个字词。例如:

SELECT
  name,
  product_description,
  retail_price,
   replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
FROM
  ecomm.products
WHERE
  name ILIKE '%wet%jacket%'
  OR name ILIKE '%jacket%wet%'
  OR name ILIKE '%jacket%'
  OR name ILIKE '%%wet%'
  OR product_description ILIKE '%wet%jacket%'
  OR product_description ILIKE '%jacket%wet%'
  OR product_description ILIKE '%jacket%'
  OR product_description ILIKE '%wet%'
LIMIT
  10;

这样会返回多行,但并非所有行都与我们对夹克的请求完全匹配,并且很难按相关性排序。例如,如果我们添加更多条件(例如“男士专用”等),查询的复杂性会显著增加。或者,我们可以尝试全文搜索,但即使这样,我们也会遇到与字词的精确程度和回答的相关性相关的限制。

现在,我们可以使用嵌入进行相似度搜索。我们已使用不同的模型预先计算了产品的嵌入内容。我们将使用 Google 最新的 gemini-embedding-001 模型。我们已将这些向量存储在 ecomm.products 表的“product_embedding”列中。如果我们使用以下查询针对“男士雨衣”搜索条件运行查询:

SELECT
  name,
  product_description,
  retail_price,
   replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_embedding <=> embedding ('gemini-embedding-001','wet conditions jacket for men')::vector AS distance
FROM
  ecomm.products
ORDER BY distance
LIMIT
  10;

它不仅会返回适合潮湿环境的夹克,还会对所有结果进行排序,将最相关的结果放在顶部。

包含嵌入的查询会在 90-150 毫秒内返回结果,其中一部分时间用于从云端嵌入模型获取数据。如果我们查看执行计划,会发现对模型的请求包含在规划时间中。执行搜索的查询部分本身非常简短。使用 AlloyDB ScaNN 索引在 2.9 万条记录中进行搜索所需的时间不到 7 毫秒。

Limit  (cost=2709.20..2718.82 rows=10 width=490) (actual time=6.966..7.049 rows=10 loops=1)
   ->  Index Scan using embedding_scann on products  (cost=2709.20..30736.40 rows=29120 width=490) (actual time=6.964..7.046 rows=10 loops=1)
         Order By: (product_embedding <=> '[-0.0020264734,-0.016582033,0.027258193
...
-0.0051468653,-0.012440448]'::vector)
         Limit: 10
 Planning Time: 136.579 ms
 Execution Time: 6.791 ms
(6 rows)

以上是使用仅限文本的嵌入模型进行的文本嵌入搜索。不过,我们也有产品图片,可以将其用于搜索。在下一章中,我们将展示多模态模型如何使用图片进行搜索。

8. 使用多模态搜索

虽然基于文本的语义搜索很有用,但描述复杂的细节可能很困难。AlloyDB 的多模态搜索功能可让用户通过输入图片来发现商品,从而提供优势。当视觉呈现比纯文本描述更能清晰表达搜索意图时,此功能尤其有用。例如,“帮我找一件像图片中这件外套一样的外套”。

我们再回到夹克示例。如果我有一张夹克的照片,而我想要找到的夹克与照片中的夹克类似,那么我可以将这张照片传递给 Google 多模态嵌入模型,并将其与我的产品图片的嵌入进行比较。在我们的表格中,product_image_embedding 列中已包含产品图片的计算嵌入内容,您可以在 product_image_embedding_model 列中查看所用的模型。

对于搜索,我们可以使用 image_embedding 函数获取图片的嵌入,并将其与预先计算的嵌入进行比较。如需启用该函数,我们需要确保使用的是正确版本的 google_ml_integration 扩展程序。

我们来验证一下当前的扩展程序版本。在 AlloyDB Studio 中执行。

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
  

如果版本低于 1.4.4,请运行以下程序。

CALL google_ml.upgrade_to_preview_version();

然后重新检查扩展程序的版本。应为 1.4.4。

以下是我的搜索图片示例,但您可以使用任何自定义图片。您只需将其上传到 Google 存储空间或其他公开可用的资源,然后将 URI 放入查询中即可。

9f33ca0c73ea2b19.png

并上传到 gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png

按图片搜索图片

首先,我们尝试仅通过图片进行搜索:

SELECT
  name,
  product_description,
  retail_price,
  replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_image_embedding <=> google_ml.image_embedding (model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector AS distance
FROM
  ecomm.products
ORDER BY distance
LIMIT
  4;

我们还在库存中找到了一些保暖外套。

图片搜索会返回与我们提供的比较图片相似的商品。正如我之前提到的,您可以尝试将自己的图片上传到公开存储分区,看看它是否能找到不同类型的服装。

我们已将 Google 的“multimodalembedding@001”模型用于图片搜索。我们的 image_embedding 函数会将图片发送到 Vertex AI,将其转换为向量,然后返回以与数据库中存储的图片向量进行比较。

我们还可以使用“EXPLAIN ANALYZE”检查它在 AlloyDB ScaNN 索引中的运行速度。

Limit  (cost=971.70..975.55 rows=4 width=490) (actual time=2.453..2.477 rows=4 loops=1)
   ->  Index Scan using product_image_embedding_scann on products  (cost=971.70..28998.90 rows=29120 width=490) (actual time=2.451..2.475 rows=4 loops=1)
         Order By: (product_image_embedding <=> '[0.02119865,0.034206174,0.030682731,
...
,-0.010307034,-0.010053742]'::vector)
         Limit: 4
 Planning Time: 913.322 ms
 Execution Time: 2.517 ms
(6 rows)

与上一个示例一样,我们可以看到,大部分时间都花在了使用云端点将图片转换为嵌入上,而向量搜索本身仅需 2.5 毫秒。

按文字搜索图片

借助多模态,我们还可以使用 google_ml.text_embedding 将要搜索的夹克的文本描述传递给同一模型,并与图片嵌入进行比较,以查看模型返回哪些图片。

SELECT
  name,
  product_description,
  retail_price,
  replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_image_embedding <=> google_ml.text_embedding (model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour')::vector AS distance
FROM
  ecomm.products
ORDER BY distance
LIMIT
  4;

我们获得了一套灰色或深色的蓬松外套。

我们获得了一组略有不同的夹克,但它根据我们的说明并通过搜索图片嵌入正确地选择了夹克。

我们来尝试另一种方法,使用搜索图片的嵌入在说明中进行搜索。

按图片中的文字搜索

我们尝试搜索图片,方法是传递图片的嵌入内容,并与预先计算的商品图片嵌入内容进行比较。我们还尝试了以下操作:传递文本请求的嵌入来搜索图片,并在同一嵌入中搜索商品图片。现在,我们尝试使用图片嵌入,并与商品说明的文本嵌入进行比较。嵌入存储在 product_description_embedding 列中,并使用相同的 multimodalembedding@001 模型。

我们的查询如下:

SELECT
  name,
  product_description,
  retail_price,
  replace(product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url,
  product_description_embedding <=> google_ml.image_embedding (model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector AS distance

FROM
  ecomm.products
ORDER BY distance
LIMIT
  4;

在这里,我们得到了一组略有不同的夹克,它们是灰色或深色的,其中一些与通过不同搜索方式选择的夹克相同或非常相似。

它会返回与上述示例中相同的夹克,但顺序略有不同。根据图片的嵌入,它可以与文本描述的计算嵌入进行比较,并返回正确的产品集。

您还可以尝试将文本嵌入和图片嵌入结合在一起,例如使用倒数排名融合。以下是一个此类查询的示例,其中我们结合了两次搜索,为每个排名分配了一个得分,并根据组合得分对结果进行排序。

WITH image_search AS (
            SELECT id,
                RANK () OVER (ORDER BY  product_image_embedding <=>google_ml.image_embedding(model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector) AS rank
                FROM ecomm.products
                ORDER BY product_image_embedding <=>google_ml.image_embedding(model_id => 'multimodalembedding@001',image => 'gs://pr-public-demo-data/alloydb-retail-demo/user_photos/4.png', mimetype => 'image/png')::vector LIMIT 5
        ),
      text_search AS (
            SELECT id,
                RANK () OVER (ORDER BY product_description_embedding <=>google_ml.text_embedding(model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour'
    )::vector) AS rank
            FROM ecomm.products
            ORDER BY product_description_embedding <=>google_ml.text_embedding(model_id => 'multimodalembedding@001',content => 'puffy jacket for men, grey or dark colour'
    )::vector LIMIT 5
        ),
      rrf_score AS (
        SELECT
            COALESCE(image_search.id, text_search.id) AS id,
            COALESCE(1.0 / (60 + image_search.rank), 0.0) + COALESCE(1.0 / (60 + text_search.rank), 0.0) AS rrf_score
        FROM image_search FULL OUTER JOIN text_search ON image_search.id = text_search.id
        ORDER BY rrf_score DESC
      )
      SELECT 
        ep.name,
        ep.product_description,
        ep.retail_price,
        replace(ep.product_image_uri,'gs://','https://storage.googleapis.com/') AS public_url
      FROM ecomm.products ep, rrf_score 
      WHERE 
        ep.id=rrf_score.id 
      ORDER by rrf_score DESC
      LIMIT 4;

您可以尝试在查询中使用不同的参数,看看是否能改善搜索结果。

这样就完成了实验,为避免产生意外费用,建议您删除未使用的资源。

此外,您还可以使用其他 AI 运算符对结果进行排名,如文档中所述。

9. 清理环境

完成实验后销毁 AlloyDB 实例和集群

删除 AlloyDB 集群和所有实例

系统会通过强制选项销毁集群,该选项还会删除属于该集群的所有实例。

如果您已断开连接且之前的所有设置都已丢失,请在 Cloud Shell 中定义项目和环境变量:

gcloud config set project <your project id>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
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.                                                                                                                                                                                                                                                            

10. 恭喜

恭喜您完成此 Codelab。您已了解如何使用 AlloyDB 中的多模态搜索功能,通过文本和图片嵌入函数进行搜索。您可以尝试测试多模态搜索,并使用 AlloyDB AI 运算符 Codelab 通过 google_ml.rank 函数对其进行改进。

所学内容

  • 如何部署 AlloyDB for Postgres
  • 如何使用多模态矢量搜索
  • 如何启用 AlloyDB AI 运算符
  • 如何使用不同的 AlloyDB AI 运算符进行多模态搜索
  • 如何使用 AlloyDB AI 组合文本和图片搜索结果

11. 调查问卷

输出如下:

您打算如何使用本教程?

仅通读 阅读并完成练习