您可以通过在 AlloyDB Omni 中创建外部数据封装容器 (FDW) 和外部表,访问和搜索存储在 Elasticsearch 中的数据。
准备工作
在开始之前,请完成以下步骤:
- 使用容器编排器安装 AlloyDB Omni。
- 部署和在生产环境中运行 Elasticsearch。
- 创建一个只读个人/用户 API 密钥,供 AlloyDB Omni 用于访问 Elasticsearch 集群。
创建服务账号
AlloyDB Omni 需要具有 Google Cloud 的服务账号才能进行身份验证并使用 Secret Manager。AlloyDB Omni 使用 Secret Manager 存储您的 Elasticsearch API 密钥。
如果您尚未为 AlloyDB Omni 创建服务账号,请按照以下步骤创建一个:
使用Google Cloud创建服务账号。您可以在使用 AlloyDB AI 创建数据库集群中向此服务账号授予访问 Secret Manager 的权限。
创建服务账号,并以 JSON 格式将其保存到
private-key.json文件中,然后下载该文件。将密钥存储在文件系统中的永久位置中。在 AlloyDB Omni 服务器的生命周期内,它都驻留在此位置。
记下其在文件系统中的位置;您在后续步骤中需要用到它。
将 Elasticsearch API 密钥存储在 Secret Manager 中
AlloyDB Omni 会将您的 Elasticsearch API 密钥存储在 Secret Manager 中,并从中读取该密钥。如需详细了解如何使用 Secret Manager,请参阅使用 Secret Manager 创建和访问 Secret。
请确保您向 AlloyDB Omni 服务账号授予了读取 Secret 的权限。如需了解详情,请参阅管理对 Secret 的访问权限。
使用 AlloyDB AI 创建数据库集群
如需使用 AlloyDB AI 创建数据库集群,请参阅在 AlloyDB Omni 中安装 AlloyDB AI。如需使用 Elasticsearch 访问和查询数据,您无需指定 vertexAI* 配置。
启用并配置 external_search_fdw 扩展程序
如需开始与 Elasticsearch 集成,请按照以下说明操作,以启用和配置 external_search_fdw AlloyDB Omni 扩展程序:
启用
external_search_fdw扩展程序。CREATE EXTENSION external_search_fdw;通过外部数据服务器配置对 Elasticsearch 集群的访问权限。
CREATE SERVER ELASTICSEARCH_SERVER_NAME FOREIGN DATA WRAPPER external_search_fdw OPTIONS (server 'ELASTICSEARCH_SERVER_HOST_PORT', search_provider 'elastic', auth_mode 'secret_manager', auth_method 'AUTH_METHOD', secret_path 'SECRET_PATH', max_deadline_ms 'MAX_DEADLINE', pagination_num_results 'PAGINATION_NUM_RESULTS', pagination_context_timeout_ms 'PAGINATION_CONTEXT_TIMEOUT');执行以下变量替换操作:
ELASTICSEARCH_SERVER_NAME:外部数据服务器的名称。例如my-elasticsearch-server。ELASTICSEARCH_SERVER_HOST_PORT:Elasticsearch 集群的公开网址。例如https://node1.elastic.test.com:9200。AUTH_METHOD:要使用的身份验证类型。您可以从以下选项中进行选择:ApiKey:Elasticsearch 个人/用户 API 密钥。Basic:Elasticsearch 用户名和密码。
SECRET_PATH:Elasticsearch 身份验证凭证的 Secret Manager 路径。例如projects/123456789012/secrets/apikey/versions/1。123456789012表示您的 Google Cloud 项目 ID。(可选)
MAX_DEADLINE:AlloyDB Omni 等待 Elasticsearch 响应的最长时间(以毫秒为单位)。请根据 AlloyDB Omni 和 Elasticsearch 实例的位置设置此值。默认值为10000。(可选)
PAGINATION_NUM_RESULTS:从 Elasticsearch 每批次提取的结果数上限。如果请求的结果数量超过此值,AlloyDB Omni 会按此大小分批检索结果。默认值为32。(可选)
PAGINATION_CONTEXT_TIMEOUT:Elasticsearch 保持分页请求上下文处于活动状态的时间(以毫秒为单位)。默认值为30000。
为 Elasticsearch 服务器定义 PostgreSQL 用户映射。请注意,PostgreSQL FDW 需要此用户映射才能正常运行。 AlloyDB Omni 使用 REST 授权标头进行身份验证。
CREATE USER MAPPING FOR CURRENT_USER SERVER ELASTICSEARCH_SERVER_NAME;通过外部数据表为 Elasticsearch 数据配置架构。
CREATE FOREIGN TABLE ELASTICSEARCH_FD_TABLE( metadata external_search_fdw_schema.OpaqueMetadata, ELASTICSEARCH_FIELDS) SERVER ELASTICSEARCH_SERVER_NAME OPTIONS(remote_table_name 'ELASTICSEARCH_INDEX_NAME');替换以下新变量:
ELASTICSEARCH_FD_TABLE:表示 Elasticsearch 表的外部数据表的名称。 例如my-fd-elasticsearch-table。ELASTICSEARCH_FIELDS:以英文逗号分隔的 Elasticsearch 字段架构定义列表,格式如下:elasticsearch_field_name PG_DATA_TYPE。例如elasticsearch_boolean_field_name BOOLEAN, elasticsearch_double_field_name DOUBLE PRECISION。 这些字段必须与 Elasticsearch 中的字段名称一致,除非附加了remote_field_name选项。例如elasticsearch_foo OPTIONS (remote_field_name 'elasticsearch_FOO')。如需查看可为 AlloyDB Omni 定义的 Elasticsearch 数据类型的列表,请参阅支持的数据类型。
ELASTICSEARCH_INDEX_NAME:Elasticsearch 索引的名称。例如my-elasticsearch-index。
支持的数据类型
AlloyDB Omni 支持以下 Elasticsearch 数据类型:
| 数据类型 | PostgreSQL 类型 |
|---|---|
alias
|
alias 引用的字段的 PostgreSQL 类型
|
binary
|
bytea
|
boolean
|
BOOLEAN
|
|
|
SMALLINT
|
date
|
TIMESTAMPTZ
|
DOUBLE PRECISION
|
|
REAL
|
|
integer
|
INTEGER
|
long
|
BIGINT
|
jsonb
|
|
|
|
TEXT
|
unsigned_long
|
NUMERIC
|
查询 Elasticsearch 数据
AlloyDB Omni 会接收 SQL 查询并将其转换为 Elasticsearch REST API 查询。在此转换期间,AlloyDB Omni 会尝试尽可能多地向下推送查询逻辑,而不会更改查询的身份,包括 SQL 查询的 LIMIT。不过,在某些情况下,您可能会指定不向下推送某些 Elasticsearch 字段,或者查询逻辑无法向下推送。例如,LIKE 和其他文本匹配运算符无法下推。如需查看更多可下推和不可下推的示例,请参阅下推示例。
在 LIMIT 设置为高于 pagination_num_results 的值,或者未指定 LIMIT 或无法下推的情况下,AlloyDB Omni 会使用 Scroll API,这可能会占用大量资源。
由于 Scroll API 可能会占用大量资源,因此我们建议您使用 EXPLAIN VERBOSE 检查查询,以了解使用了哪些 API。限制 Scroll API 的使用并使用 LIMIT 可提高性能。
如需查询 Elasticsearch 数据,您可以使用以下选项:
- 标准 SQL 查询
- 查询 DSL
- 混合搜索
标准 SQL 查询
可以使用 Elasticsearch 的 Lucene 语法编写标准 SQL 查询。
如需执行标准 SQL 查询,请参阅以下示例查询:
SELECT id, body
FROM ELASTICSEARCH_FD_TABLE
WHERE FILTER
ORDER BY metadata <@> 'QUERY';
执行以下变量替换操作:
ELASTICSEARCH_FD_TABLE:表示 Elasticsearch 表的外部数据表的名称。例如my-fd-elasticsearch-table。(可选)
FILTER:要应用于 Elasticsearch 查询的过滤条件。例如AND qubits < 105。QUERY:要发送到 Elasticsearch 的查询。如需查看一些查询示例,请参阅以下列表:body:quantum body:computingbody:(quantum computing)body:(quantum AND computing)body:"quantum computing"body:"quantum computing" AND qubits:[* TO 105}
查询 DSL
Query DSL 是 Elasticsearch 的全功能 JSON 样式查询语言,建议用于高级用例。借助查询 DSL,您可以执行无法用 SQL 查询语法表达的复杂搜索、过滤和聚合。
如需使用 Query DSL 执行查询,请参阅以下示例查询:
SELECT id, body
FROM ELASTICSEARCH_FD_TABLE
ORDER BY
metadata <@> $${
"query": {
"bool": {
"must": [
{
"query_string": {
"query" : "QUERY"
}
}
],
"filter": [
{
"range": {
"id": {
"lt": "10"
}
}
}
]
}
},
"sort": [
{
"id": {
"order": "desc"
}
}
]
}$$
LIMIT 1;
执行以下变量替换操作:
ELASTICSEARCH_FD_TABLE:表示 Elasticsearch 表的外表名称。例如my-fd-elasticsearch-table。QUERY:要发送到 Elasticsearch 的查询。例如"elasticsearch_field_name:\"quantum computing\" OR int_field:[* TO 3]"。
请注意,对于 Query DSL,您只需传播 query、filter 和 sort 表达式。
混合搜索
如需对 Elasticsearch 数据执行混合搜索,请参阅以下搜索示例:
SELECT *
FROM
ai.hybrid_search(
ARRAY[
'{"limit": LIMIT,
"data_type": "external_search_fdw",
"weight": WEIGHT,
"table_name": "ELASTICSEARCH_FD_TABLE",
"key_column": "DOCUMENT_ID_COLUMN_NAME",
"query_text_input": QUERY}'::jsonb],
NULL::TEXT,
'RRF',
FALSE)
ORDER BY score DESC;
执行以下变量替换操作:
LIMIT:要返回的结果数。例如3。WEIGHT:此搜索条目对整体倒数排序融合 (RRF) 的贡献。例如0.5。如果您未提供权重,系统会均匀分配权重。如需了解详情,请参阅混合搜索函数参数。ELASTICSEARCH_FD_TABLE:表示 Elasticsearch 表的外部数据表的名称。例如my-fd-elasticsearch-table。DOCUMENT_ID_COLUMN_NAME: 文档 ID 列的名称。QUERY:要发送到 Elasticsearch 的查询。例如,"elasticsearch_field_name:\"quantum computing\""会在elasticsearch_field_name字段中搜索短语“quantum computing”。支持的数据类型中提及的所有查询类型都可以在查询中使用。
如需详细了解可用于混合搜索的参数,请参阅混合搜索函数参数。
下推示例
为了提高查询效率,AlloyDB Omni 会尝试将查询的以下方面直接下推到对 Elasticsearch 进行的 API 调用中:
SELECT个字段WHERE个过滤条件ORDER BY种排序LIMIT
如需查看显示 AlloyDB Omni 能够和不能下推哪些方面的示例查询,请参阅下表。
| 查询类型 | 查询示例 | 下推的查询元素 |
|---|---|---|
| 未过滤的查询 |
SELECT id, body FROM elasticsearch_table ORDER BY metadata <@> 'body:foo' DESC LIMIT 10; |
|
| 完全匹配文本 |
SELECT id, body FROM elasticsearch_table WHERE body = 'foo' LIMIT 10; |
|
| 单字段表达式 |
SELECT id, body FROM elasticsearch_table WHERE id > 10 ORDER BY metadata <@> 'body:foo' LIMIT 10; |
|
| 常量表达式 |
SELECT id, body FROM elasticsearch_table WHERE id > (1+1) LIMIT 10; |
|
| 包含函数的表达式 |
SELECT id, body FROM elasticsearch_table WHERE id > CEIL(3.14) LIMIT 10; |
|
| 多字段表达式 |
SELECT id, body FROM elasticsearch_table WHERE dbl_field < flt_field LIMIT 10; |
|
| 分数过滤 |
SELECT id, body, (metadata <@> 'body:bar') AS score FROM elasticsearch_table WHERE score > 0.5 ORDER by score desc LIMIT 10; |
|
LIKE 和类似运算符 |
SELECT id, body FROM elasticsearch_table WHERE id > 10 AND body LIKE '%foo%' LIMIT 10; |
|
| 原始查询 |
SELECT id, body FROM elasticsearch_table WHERE id < 10 ORDER BY metadata <@> $${"query": { "match_all": {}}}$$ DESC LIMIT 10; |
|
问题排查
如果您在查询 Elasticsearch 集群时遇到身份验证或连接问题,请检查以下方面:
- HTTP 401 或 403 身份验证错误:验证 Secret Manager 中的 Elasticsearch Secret 是否包含
auth_method(ApiKey或Basic)的有效身份验证凭据,并验证您的服务账号是否具有secretmanager.secretAccessor权限。 - 连接超时:验证 AlloyDB Omni 与 Elasticsearch 端点之间的网络规则和防火墙配置。
限制
AlloyDB Omni 会读取 Elasticsearch 数据,但不会向其写入数据。
您需要负责在 AlloyDB Omni 和 Elasticsearch 之间同步数据。
后续步骤
- 了解如何访问 OpenSearch 数据。
- 了解如何访问 Solr 数据。
- 了解如何运行混合向量相似性搜索。