AlloyDB for PostgreSQL で外部データラッパー(FDW)と外部テーブルを作成して、Elasticsearch に保存されているデータにアクセスして検索します。
始める前に
始める前に、次のことを完了していることを確認してください。
プライマリ AlloyDB インスタンスでアウトバウンド接続を有効にします。
AlloyDB が Elasticsearch クラスタにアクセスするために使用できる、読み取り専用の個人 / ユーザー API キーを作成します。
Elasticsearch API キーを Secret Manager に保存する
AlloyDB は、Secret Manager から Elasticsearch API キーを保存して読み取ります。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
Query DSL は、Elasticsearch のフル機能の JSON スタイルのクエリ言語で、高度なユースケースに推奨されます。Query 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-tableQUERY: Elasticsearch に送信するクエリ。例:"elasticsearch_field_name:\"quantum computing\" OR int_field:[* TO 3]"
Query 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フィールドで「量子コンピューティング」というフレーズを検索します。サポートされているデータ型に記載されているすべてのクエリタイプをクエリで使用できます。
ハイブリッド検索で使用できるパラメータの詳細については、ハイブリッド検索関数のパラメータをご覧ください。
プッシュダウンの例
クエリをより効率的にするため、AlloyDB はクエリの次の要素を Elasticsearch への API 呼び出しに直接 push down しようとします。
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; |
|
トラブルシューティング
Elasticsearch クラスタのクエリ時に認証または接続の問題が発生した場合は、次の一般的な原因を確認してください。
- HTTP 401 または 403 認証エラー: Secret Manager の Elasticsearch シークレットに
auth_method(ApiKeyまたはBasic)の有効な認証情報が含まれていることを確認します。また、AlloyDB で使用されるサービス アカウントにsecretmanager.secretAccessor権限があることを確認します。 - 接続タイムアウト: プライマリ AlloyDB インスタンスでアウトバウンド パブリック IP 接続が有効になっていること、および Elasticsearch ファイアウォールで指定されたポートでの受信接続が許可されていることを確認します。
制限事項
AlloyDB を Elasticsearch に接続する前に、次の制限事項を確認してください。
Elasticsearch の統合は、PostgreSQL メジャー バージョン
17以降でのみ利用できます。AlloyDB は Elasticsearch データの読み取りを行いますが、書き込みは行いません。
AlloyDB と Elasticsearch 間のデータの同期は、ユーザーが行う必要があります。
geo_pointなどの特殊な Elasticsearch タイプはサポートされていません。サポートされているデータ型の全一覧については、サポートされているデータ型をご覧ください。
次のステップ
- OpenSearch データにアクセスする方法を確認する。
- Solr データにアクセスする方法を確認する。
- ハイブリッド ベクトル類似性検索を実行する方法を学ぶ。