從 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. 將您建立的服務帳戶金鑰複製到 KEY_PATH。金鑰路徑必須是主機上的路徑,且可由執行 AlloyDB Omni 容器的使用者存取及擁有。

將 Elasticsearch API 金鑰儲存在 Secret Manager

AlloyDB Omni 會從 Secret Manager 儲存及讀取 Elasticsearch API 金鑰。如要進一步瞭解如何使用 Secret Manager,請參閱「使用 Secret Manager 建立及存取密鑰」。

請務必授予 AlloyDB Omni 服務帳戶讀取 Secret 的權限。詳情請參閱「管理密鑰存取權」。

設定 AlloyDB Omni 的 AlloyDB AI

如要為 AlloyDB Omni 設定 AlloyDB AI,請參閱「為 AlloyDB Omni 設定 AlloyDB AI」,並略過第一個步驟。

啟用及設定 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。除非附加 remote_field_name 選項,否則這些欄位必須與 Elasticsearch 中的欄位名稱相符。例如: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 會使用捲動 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 樣式查詢語言,建議用於進階用途。Query 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) 的貢獻。例如: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 密鑰包含 auth_method (ApiKey 或 Basic) 的有效驗證憑證,並確認服務帳戶具備 secretmanager.secretAccessor 權限。
  • 連線逾時:請驗證 AlloyDB Omni 和 Elasticsearch 端點之間的網路規則和防火牆設定。

限制

  • AlloyDB Omni 會讀取 Elasticsearch 資料,但不會寫入。

  • 您必須負責同步處理 AlloyDB Omni 和 Elasticsearch 之間的資料。

  • 不支援 geo_point 等特殊 Elasticsearch 類型。詳情請參閱「支援的資料類型」。

後續步驟