AlloyDB for PostgreSQL で外部データ ラッパー(FDW)と外部テーブルを作成して、 Elasticsearchに保存されているデータにアクセスして検索します。
制限事項
AlloyDB を Elasticsearch に接続する前に、次の制限事項を確認してください。
Elasticsearch の統合は、PostgreSQL のメジャー バージョン
17以降でのみ使用できます。AlloyDB は Elasticsearch データを読み取りますが、書き込みは行いません。
AlloyDB と Elasticsearch 間のデータ同期は、お客様の責任で行ってください。
geo_pointなどの特殊な Elasticsearch タイプは対象外です。サポートされているデータ型の完全なリストについては、 サポートされているデータ型をご覧ください。
始める前に
始める前に、次の操作が完了していることを確認してください。
アウトバウンド接続を有効にする プライマリ AlloyDB インスタンスで
AlloyDB が Elasticsearch クラスタへのアクセスに使用できる読み取り専用の 個人/ユーザー API キー を作成する
Elasticsearch API キーを Secret Manager に保存する
AlloyDB は、Elasticsearch API キーを Secret Manager に保存して読み取ります。Secret Manager の使用方法の詳細については、 Secret Manager を使用してシークレットを作成してアクセスするをご覧ください。
AlloyDB サービス アカウントにシークレットの読み取り権限を付与してください。詳細については、 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-serverELASTICSEARCH_SERVER_HOST_PORT: Elasticsearch クラスタの公開 URL。例:https://node1.elastic.test.com:9200AUTH_METHOD: 使用する認証のタイプ。次のオプションから選択できます。ApiKey: Elasticsearch 個人/ユーザー API キー.Basic: Elasticsearch のユーザー名とパスワード。
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です。
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-tableELASTICSEARCH_FIELDS: 次の形式の Elasticsearch フィールド スキーマ定義のカンマ区切りのリスト:elasticsearch_field_name PG_DATA_TYPE。例:elasticsearch_boolean_field_name BOOLEAN, elasticsearch_double_field_name DOUBLE PRECISIONremote_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 など、クエリの ID を変更せずに、可能な限り多くのクエリ ロジックをプッシュダウンしようとします。ただし、特定の Elasticsearch フィールドをプッシュダウンしないように指定する場合や、クエリ ロジックをプッシュダウンできない場合があります。たとえば、LIKE などのテキスト一致演算子はプッシュダウンできません。プッシュダウンできるものとできないものの例については、プッシュダウンの例をご覧ください。
LIMIT が pagination_num_results より大きい場合、または LIMIT が指定されていないかプッシュダウンできない場合、AlloyDB はリソースを大量に消費する可能性がある Scroll 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 < 105QUERY: 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 クエリ構文では表現できない複雑な検索、フィルタリング、集計を実行できます。
クエリ 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-tableQUERY: 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: 返す結果の数。例:3WEIGHT: この検索エントリが Reciprocal Rank Fusion(RRF)全体に与える影響。ELASTICSEARCH_FD_TABLE: Elasticsearch テーブルを表す外部データテーブルの名前。例:my-fd-elasticsearch-tableDOCUMENT_ID_COLUMN_NAME: ドキュメント ID 列の名前。QUERY: Elasticsearch に送信するクエリ。たとえば、"elasticsearch_field_name:\"quantum computing\""は、elasticsearch_field_nameフィールドで "quantum computing" というフレーズを検索します。サポートされているデータ型 で説明されているすべてのクエリタイプをクエリで使用できます。
ハイブリッド検索で使用できるパラメータの詳細については、 ハイブリッド検索関数のパラメータをご覧ください。
プッシュダウンの例
クエリをより効率的にするために、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; |
|