从 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 服务账号授予了读取密文的权限。如需了解详情,请参阅管理对密文的访问权限

使用 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/1123456789012 表示您的 Google Cloud 项目 ID。

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

    • (可选)PAGINATION_NUM_RESULTS:每次从 Elasticsearch 提取的最大结果数。如果请求更多结果,AlloyDB Omni 会分多个批次检索结果,每个批次的大小为 100。默认值为 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 或无法下推 LIMIT,AlloyDB Omni 会使用滚动 API,这可能会消耗大量资源。

由于 Scroll API 可能会消耗大量资源,因此我们建议您使用 EXPLAIN VERBOSE 检查查询,看看使用了哪些 API。限制 Scroll API 的使用并使用 LIMIT 可提高性能。

如需查询 Elasticsearch 数据,您可选择以下方式:

  • 标准 SQL 查询
  • 查询 DSL
  • 混合搜索

标准 SQL 查询

标准 SQL 查询可以使用 Elasticsearch 的 Lucene 语法编写。

如需执行标准 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 查询语法表达的复杂搜索、过滤和聚合。

如需使用 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]"

请注意,对于查询 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) 的贡献。例如 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_methodApiKeyBasic)的有效身份验证凭据,并验证您的服务账号是否具有 secretmanager.secretAccessor 权限。
  • 连接超时:验证 AlloyDB Omni 与 Elasticsearch 端点之间的网络规则和防火墙配置。

限制

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

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

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

后续步骤