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

PostgreSQL용 AlloyDB에서 외부 데이터 래퍼 (FDW)와 외부 테이블을 만들어 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 쿼리
  • Query 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}

Query 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 정렬

문제 해결

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 유형은 지원되지 않습니다. 지원되는 데이터 유형의 전체 목록은 지원되는 데이터 유형을 참고하세요.

다음 단계