从 AlloyDB Omni 访问 Elasticsearch 数据

选择文档版本:

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

准备工作

在开始之前,请完成以下步骤:

创建服务账号

AlloyDB Omni 需要具有 Google Cloud 的服务账号才能进行身份验证并使用 Secret Manager。AlloyDB Omni 使用 Secret Manager 存储您的 Elasticsearch API 密钥。

如果您尚未为 AlloyDB Omni 创建服务账号,请按照以下步骤创建一个:

  1. 使用Google Cloud创建服务账号。您可以在使用 AlloyDB AI 创建数据库集群中向此服务账号授予访问 Secret Manager 的权限。

  2. 创建服务账号,并以 JSON 格式将其保存到 private-key.json 文件中,然后下载该文件。

  3. 将密钥存储在文件系统中的永久位置中。在 AlloyDB Omni 服务器的生命周期内,它都驻留在此位置。

    记下其在文件系统中的位置;您在后续步骤中需要用到它。

  4. 使用服务账号密钥创建 Kubernetes Secret。

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

  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/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。

  3. 为 Elasticsearch 服务器定义 PostgreSQL 用户映射。请注意,PostgreSQL FDW 需要此用户映射才能正常运行。 AlloyDB Omni 使用 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。 这些字段必须与 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

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 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:computing
    • body:(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 个字段
  • 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 排序

问题排查

如果您在查询 Elasticsearch 集群时遇到身份验证或连接问题,请检查以下方面:

  • HTTP 401 或 403 身份验证错误:验证 Secret Manager 中的 Elasticsearch Secret 是否包含 auth_method(ApiKey 或 Basic)的有效身份验证凭据,并验证您的服务账号是否具有 secretmanager.secretAccessor 权限。
  • 连接超时:验证 AlloyDB Omni 与 Elasticsearch 端点之间的网络规则和防火墙配置。

限制

  • AlloyDB Omni 会读取 Elasticsearch 数据,但不会向其写入数据。

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

  • 不支持专用 Elasticsearch 类型,例如 geo_point。如需了解详情,请参阅支持的数据类型。

后续步骤