PostgreSQL용 AlloyDB에서 Elasticsearch 데이터에 액세스

PostgreSQL용 AlloyDB에서 외부 데이터 래퍼 (FDW)와 외부 테이블을 만들어 Elasticsearch에 저장된 데이터에 액세스하고 검색합니다.

제한사항

AlloyDB를 Elasticsearch에 연결하기 전에 다음 제한사항을 확인하세요.

  • Elasticsearch 통합은 PostgreSQL 메이저 버전 17 이상에서만 사용할 수 있습니다.

  • AlloyDB는 Elasticsearch 데이터를 읽지만 쓰지는 않습니다.

  • AlloyDB와 Elasticsearch 간의 데이터 동기화는 사용자가 담당합니다.

  • geo_point과 같은 전문 Elasticsearch 유형은 지원되지 않습니다. 지원되는 데이터 유형의 전체 목록은 지원되는 데이터 유형을 참고하세요.

시작하기 전에

시작하기 전에 다음 작업을 완료했는지 확인하세요.

Secret Manager에 Elasticsearch API 키 저장

AlloyDB는 Secret Manager에서 Elasticsearch API 키를 저장하고 읽습니다. Secret Manager 사용 방법에 대한 자세한 내용은 Secret Manager를 사용하여 보안 비밀 만들기 및 액세스를 참고하세요.

AlloyDB 서비스 계정에 보안 비밀을 읽을 수 있는 권한을 부여해야 합니다. 자세한 내용은 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 클러스터의 공개 URL입니다. 예를 들면 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입니다.

  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를 비롯한 쿼리의 ID를 변경하지 않고 가능한 한 많은 쿼리 로직을 푸시하려고 시도합니다. 하지만 특정 Elasticsearch 필드를 푸시하지 않도록 지정하거나 쿼리 로직을 푸시할 수 없는 경우가 있습니다. 예를 들어 LIKE 및 기타 텍스트 일치 연산자는 푸시 다운할 수 없습니다. 푸시다운할 수 있는 항목과 푸시다운할 수 없는 항목의 예는 푸시다운 예시를 참고하세요.

LIMITpagination_num_results보다 높게 설정되거나 LIMIT이 지정되지 않거나 푸시 다운할 수 없는 시나리오에서 AlloyDB는 리소스 집약적일 수 있는 스크롤 API를 사용합니다.

스크롤 API는 리소스를 많이 사용할 수 있으므로 EXPLAIN VERBOSE를 사용하여 쿼리를 검사하여 사용되는 API를 확인하는 것이 좋습니다. 스크롤 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 < 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의 경우 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
  • 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 정렬