您可以通过在 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文件中,然后下载该文件。将您创建的服务账号密钥复制到
KEY_PATH。密钥路径必须是主机上可访问且由运行 AlloyDB Omni 容器的用户拥有的路径。
将 Elasticsearch API 密钥存储在 Secret Manager 中
AlloyDB Omni 会在 Secret Manager 中存储和读取 Elasticsearch API 密钥。如需详细了解如何使用 Secret Manager,请参阅使用 Secret Manager 创建和访问 Secret。
请确保您向 AlloyDB Omni 服务账号授予了读取 Secret 的权限。如需了解详情,请参阅管理对 Secret 的访问权限。
为 AlloyDB Omni 配置 AlloyDB AI
如需为 AlloyDB Omni 配置 AlloyDB AI,请参阅为 AlloyDB Omni 配置 AlloyDB AI,并跳过第一步。
启用并配置 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 密钥是否包含
auth_method(ApiKey或Basic)的有效身份验证凭证,并验证您的服务账号是否具有secretmanager.secretAccessor权限。 - 连接超时:验证 AlloyDB Omni 与 Elasticsearch 端点之间的网络规则和防火墙配置。
限制
AlloyDB Omni 会读取 Elasticsearch 数据,但不会向其写入数据。
您需要负责在 AlloyDB Omni 和 Elasticsearch 之间同步数据。
后续步骤
- 了解如何访问 OpenSearch 数据。
- 了解如何访问 Solr 数据。
- 了解如何运行混合向量相似性搜索。