通过在 AlloyDB for PostgreSQL 中创建外部数据 封装容器 (FDW) 和外部表,访问和搜索存储在 Elasticsearch中的数据。
限制
在将 AlloyDB 连接到 Elasticsearch 之前,请了解以下限制:
Elasticsearch 集成仅适用于 PostgreSQL 主要版本
17及更高版本。AlloyDB 可以读取 Elasticsearch 数据,但无法写入。
您负责在 AlloyDB 和 Elasticsearch 之间同步数据。
不支持专用 Elasticsearch 类型,例如
geo_point。如需查看支持的数据类型的完整列表,请参阅 支持的数据类型。
准备工作
在开始之前,请确保您已完成以下操作:
创建集群。
启用出站连接 在主 AlloyDB 实例上。
创建一个只读的 个人/用户 API 密钥 ,AlloyDB 可以使用该密钥访问您的 Elasticsearch 集群。
将 Elasticsearch API 密钥存储在 Secret Manager 中
AlloyDB 会从 Secret Manager 存储和读取您的 Elasticsearch API 密钥。如需详细了解如何使用 Secret Manager,请参阅 使用 Secret Manager 创建和访问 Secret。
确保您向 AlloyDB 服务帐号授予读取 Secret 的权限。如需了解详情,请参阅 使用 Secret Manager 创建和访问 Secret。
启用和配置 external_search_fdw 扩展程序
如需开始与 Elasticsearch 集成,请按照以下
说明启用和配置
external_search_fdw
AlloyDB 扩展程序:
启用
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 等待 Elasticsearch 响应的最长时间(以毫秒为单位)。您应根据 AlloyDB 和 Elasticsearch 实例的位置设置此值。默认值为10000。(可选)
PAGINATION_NUM_RESULTS:每次从 Elasticsearch 提取的最大结果数。如果请求的结果较多,AlloyDB 会分批检索结果,每批结果的大小为此值。默认值为32。(可选)
PAGINATION_CONTEXT_TIMEOUT:Elasticsearch 使分页请求上下文保持活动状态的时间(以毫秒为单位)。默认值为30000。
为 Elasticsearch 服务器定义 PostgreSQL 用户映射。请注意,PostgreSQL FDW 需要此用户映射才能正常运行。 AlloyDB 使用 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。 除非附加了remote_field_name选项,否则这些字段必须与 Elasticsearch 中的字段名称匹配。例如,elasticsearch_foo OPTIONS (remote_field_name 'elasticsearch_FOO')。如需查看可为 AlloyDB 定义的 Elasticsearch 数据类型列表,请参阅 支持的数据类型。
ELASTICSEARCH_INDEX_NAME:Elasticsearch 索引的名称。例如,my-elasticsearch-index。
支持的数据类型
AlloyDB 支持以下 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 接受 SQL 查询,并将其转换为 Elasticsearch REST API 查询。在此转换过程中,AlloyDB 会尝试尽可能多地推送查询逻辑,而不会更改查询的身份,包括 SQL 查询的 LIMIT。不过,在某些情况下,您可能会指定不推送某些 Elasticsearch 字段,或者无法推送查询逻辑。例如,LIKE 和其他文本匹配运算符无法推送。如需查看可以推送和无法推送的内容的更多示例,请参阅推送示例。
在 LIMIT 设置高于 pagination_num_results 的场景中,或者在未指定 LIMIT 或无法推送 LIMIT 的场景中,AlloyDB 会使用 Scroll API,该 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
查询 DSL 是 Elasticsearch 的功能齐全的 JSON 样式查询语言,建议用于 高级使用场景。借助查询 DSL,您可以执行复杂的搜索、过滤和聚合,这些操作无法在 SQL 查询语法中表达。
如需使用 查询 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]"。
请注意,对于查询 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) 的贡献。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 会尝试将查询的以下方面直接推送到对 Elasticsearch 发出的 API 调用中:
SELECT字段WHERE过滤条件ORDER BY排序LIMIT
如需查看说明 AlloyDB 能够推送和无法推送哪些方面的示例查询,请参阅下表。
| 查询类型 | 查询示例 | 推送的查询元素 |
|---|---|---|
| 未过滤的查询 |
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; |
|