在 AlloyDB for PostgreSQL 中建立外部資料包裝函式 (FDW) 和外部資料表,即可存取及搜尋儲存在 Elasticsearch 中的資料。
限制
將 AlloyDB 連線至 Elasticsearch 前,請先瞭解下列限制:
Elasticsearch 整合功能僅適用於 PostgreSQL 主要版本
17以上。AlloyDB 會讀取 Elasticsearch 資料,但不會寫入。
您必須負責同步處理 AlloyDB 和 Elasticsearch 之間的資料。
系統不支援專門的 Elasticsearch 類型,例如
geo_point。如需支援的資料類型完整清單,請參閱「支援的資料類型」。
事前準備
開始之前,請確認您已完成下列事項:
建立叢集。
在主要 AlloyDB 執行個體上啟用輸出連線。
建立唯讀的個人/使用者 API 金鑰,供 AlloyDB 用於存取 Elasticsearch 叢集。
將 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 擴充功能:
啟用
external_search_fdw擴充功能。CREATE EXTENSION external_search_fdw;透過外部資料伺服器設定 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:要使用的驗證類型。你可以選擇下列任一選項:ApiKey:Elasticsearch 個人/使用者 API 金鑰。Basic:Elasticsearch 使用者名稱和密碼。
SECRET_PATH: Elasticsearch 驗證憑證的 Secret Manager 路徑。例如:projects/123456789012/secrets/apikey/versions/1。123456789012代表您的 Google Cloud 專案 ID。(選用)
MAX_DEADLINE: AlloyDB 等候 Elasticsearch 回應的時間上限 (以毫秒為單位)。您應根據 AlloyDB 和 Elasticsearch 執行個體的位置設定這個值。預設值為10000。(選用)
PAGINATION_NUM_RESULTS: 從 Elasticsearch 擷取每個批次結果的數量上限。如果要求更多結果,AlloyDB 會以這個大小分批擷取結果。預設值為32。(選用)
PAGINATION_CONTEXT_TIMEOUT: Elasticsearch 讓分頁要求情境保持有效狀態的時間長度,以毫秒為單位。預設值為30000。
為 Elasticsearch 伺服器定義 PostgreSQL 使用者對應。請注意,PostgreSQL FDW 需要這個使用者對應才能運作。AlloyDB 會使用 REST 授權標頭進行驗證。
CREATE USER MAPPING FOR CURRENT_USER SERVER ELASTICSEARCH_SERVER_NAME;透過外部資料表設定 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
|
|
|
SMALLINT
|
date
|
TIMESTAMPTZ
|
DOUBLE PRECISION
|
|
REAL
|
|
integer
|
INTEGER
|
long
|
BIGINT
|
jsonb
|
|
|
|
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:computingbody:(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,您只需要傳播 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) 的貢獻。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 id, body FROM elasticsearch_table WHERE body = 'foo' LIMIT 10; |
|
| 單一欄位運算式 |
SELECT id, body FROM elasticsearch_table WHERE id > 10 ORDER BY metadata <@> 'body:foo' LIMIT 10; |
|
| 常數運算式 |
SELECT id, body FROM elasticsearch_table WHERE id > (1+1) LIMIT 10; |
|
| 含函式的運算式 |
SELECT id, body FROM elasticsearch_table WHERE id > CEIL(3.14) LIMIT 10; |
|
| 多欄位運算式 |
SELECT id, body FROM elasticsearch_table WHERE dbl_field < flt_field LIMIT 10; |
|
| 分數篩選 |
SELECT id, body, (metadata <@> 'body:bar') AS score FROM elasticsearch_table WHERE score > 0.5 ORDER by score desc LIMIT 10; |
|
LIKE 和類似運算子 |
SELECT id, body FROM elasticsearch_table WHERE id > 10 AND body LIKE '%foo%' LIMIT 10; |
|
| 原始查詢 |
SELECT id, body FROM elasticsearch_table WHERE id < 10 ORDER BY metadata <@> $${"query": { "match_all": {}}}$$ DESC LIMIT 10; |
|