从 AlloyDB for PostgreSQL 访问 Elasticsearch 数据

通过在 AlloyDB for PostgreSQL 中创建外部数据 封装容器 (FDW) 和外部表,访问和搜索存储在 Elasticsearch中的数据。

限制

在将 AlloyDB 连接到 Elasticsearch 之前,请了解以下限制:

  • Elasticsearch 集成仅适用于 PostgreSQL 主要版本 17 及更高版本。

  • AlloyDB 可以读取 Elasticsearch 数据,但无法写入。

  • 您负责在 AlloyDB 和 Elasticsearch 之间同步数据。

  • 不支持专用 Elasticsearch 类型,例如 geo_point 。如需查看支持的数据类型的完整列表,请参阅 支持的数据类型

准备工作

在开始之前,请确保您已完成以下操作:

将 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 扩展程序:

  1. 启用 external_search_fdw 扩展程序。

    CREATE EXTENSION external_search_fdw;
    
  2. 通过外部数据服务器配置对 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:要使用的身份验证类型。您可以从以下选项中进行选择:

    • SECRET_PATH:Elasticsearch 身份验证凭据的 Secret Manager 路径。例如,projects/123456789012/secrets/apikey/versions/1123456789012 表示您的 Google Cloud 项目 ID。

    • (可选)MAX_DEADLINE:AlloyDB 等待 Elasticsearch 响应的最长时间(以毫秒为单位)。您应根据 AlloyDB 和 Elasticsearch 实例的位置设置此值。默认值为 10000

    • (可选)PAGINATION_NUM_RESULTS:每次从 Elasticsearch 提取的最大结果数。如果请求的结果较多,AlloyDB 会分批检索结果,每批结果的大小为此值。默认值为 32

    • (可选)PAGINATION_CONTEXT_TIMEOUT:Elasticsearch 使分页请求上下文保持活动状态的时间(以毫秒为单位)。默认值为 30000

  3. 为 Elasticsearch 服务器定义 PostgreSQL 用户映射。请注意,PostgreSQL FDW 需要此用户映射才能正常运行。 AlloyDB 使用 REST 授权标头进行身份验证。

    CREATE USER MAPPING FOR CURRENT_USER
           SERVER ELASTICSEARCH_SERVER_NAME;
    
  4. 通过外部数据表配置 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

byte

short

SMALLINT
date TIMESTAMPTZ

double

scaled_float

DOUBLE PRECISION

float

half_float

REAL
integer INTEGER
long BIGINT

object

flattened

jsonb

text

annotated_text

keyword

constant_keyword

wildcard

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:computing
    • body:(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,您只需传播 queryfiltersort 表达式。

如需对 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 字段
  • ORDER BY ... DESC 排序
  • LIMIT
完全匹配文本
SELECT id, body
FROM elasticsearch_table
WHERE body = 'foo'
LIMIT 10;
  • SELECT 字段
  • WHERE 过滤条件
  • LIMIT
单字段表达式
SELECT id, body
FROM elasticsearch_table
WHERE id > 10
ORDER BY metadata <@> 'body:foo'
LIMIT 10;
  • SELECT 字段
  • WHERE 过滤条件
常量表达式
SELECT id, body
FROM elasticsearch_table
WHERE id > (1+1)
LIMIT 10;
  • SELECT 字段
  • WHERE 过滤条件
  • LIMIT
包含函数的表达式
SELECT id, body
FROM elasticsearch_table
WHERE id > CEIL(3.14)
LIMIT 10;
  • SELECT 字段
多字段表达式
SELECT id, body
FROM elasticsearch_table
WHERE dbl_field < flt_field
LIMIT 10;
  • SELECT 字段
得分过滤
SELECT id, body, (metadata <@> 'body:bar') AS score
FROM elasticsearch_table
WHERE score > 0.5
ORDER by score desc
LIMIT 10;
  • SELECT 字段
  • ORDER BY ... DESC 排序
LIKE 和类似运算符
SELECT id, body
FROM elasticsearch_table
WHERE id > 10 AND body LIKE '%foo%'
LIMIT 10;
  • SELECT 字段
  • WHERE id > 10 过滤条件
原始查询
SELECT id, body
FROM elasticsearch_table
WHERE id < 10
ORDER BY metadata <@> $${"query": { "match_all": {}}}$$ DESC
LIMIT 10;
  • SELECT 字段
  • ORDER BY ... DESC 排序