從 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 建立及存取密鑰」。

請務必授予 AlloyDB 服務帳戶讀取 Secret 的權限。詳情請參閱「使用 Secret Manager 建立及存取密鑰」。

啟用及設定 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 或無法向下推送,AlloyDB 會使用捲動 API,這可能會耗用大量資源。

由於捲動 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 查詢語法表示。

如要使用 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) 的貢獻。

  • ELASTICSEARCH_FD_TABLE:代表 Elasticsearch 資料表的外來資料表名稱。例如:my-fd-elasticsearch-table

  • DOCUMENT_ID_COLUMN_NAME: 文件 ID 資料欄的名稱。

  • QUERY:要傳送至 Elasticsearch 的查詢。舉例來說,"elasticsearch_field_name:\"quantum computing\"" 會在 elasticsearch_field_name 欄位中搜尋「量子運算」這個詞組。您可以在查詢中使用「支援的資料類型」中提及的所有查詢類型。

如要進一步瞭解混合式搜尋可用的參數,請參閱混合式搜尋函式參數

下推式廣告範例

為提高查詢效率,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 排序