Acessar dados do Elasticsearch no AlloyDB para PostgreSQL

Acesse e pesquise dados armazenados no Elasticsearch criando um wrapper de dados externos (FDW, na sigla em inglês) e uma tabela externa no AlloyDB para PostgreSQL.

Antes de começar

Antes de começar, verifique se você concluiu o seguinte:

Armazenar a chave de API do Elasticsearch no Secret Manager

O AlloyDB armazena e lê sua chave de API do Elasticsearch no Secret Manager. Para mais informações sobre como usar o Secret Manager, consulte Criar e acessar um secret usando o Secret Manager.

Conceda à conta de serviço do AlloyDB permissão para ler o secret. Para mais informações, consulte Criar e acessar um secret usando o Secret Manager.

Ativar e configurar a extensão external_search_fdw

Para iniciar a integração com o Elasticsearch, siga as instruções abaixo para ativar e configurar a extensão external_search_fdw do AlloyDB:

  1. Ative a extensão external_search_fdw.

    CREATE EXTENSION external_search_fdw;
    
  2. Configure o acesso ao cluster do Elasticsearch por um servidor de dados externo.

    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');
    

    Substitua as seguintes variáveis:

    • ELASTICSEARCH_SERVER_NAME: nome do servidor de dados externo. Por exemplo, my-elasticsearch-server.

    • ELASTICSEARCH_SERVER_HOST_PORT: URL público do cluster do Elasticsearch. Por exemplo, https://node1.elastic.test.com:9200.

    • AUTH_METHOD: tipo de autenticação a ser usado. Você pode escolher entre as seguintes opções:

    • SECRET_PATH: caminho do Secret Manager para suas credenciais de autenticação do Elasticsearch. Por exemplo, projects/123456789012/secrets/apikey/versions/1. 123456789012 representa o ID do projeto do Google Cloud .

    • (Opcional) MAX_DEADLINE: tempo máximo, em milissegundos, que o AlloyDB aguarda uma resposta do Elasticsearch. Defina esse valor com base nos locais das instâncias do AlloyDB e do Elasticsearch. O valor padrão é 10000.

    • (Opcional) PAGINATION_NUM_RESULTS: número máximo de resultados buscados por lote no Elasticsearch. Se mais resultados forem solicitados, o AlloyDB vai recuperar os resultados em vários lotes desse tamanho. O valor padrão é 32.

    • (Opcional) PAGINATION_CONTEXT_TIMEOUT: tempo, em milissegundos, que o Elasticsearch mantém o contexto da solicitação de paginação ativo. O valor padrão é 30000.

  3. Defina o mapeamento de usuários do PostgreSQL para o servidor do Elasticsearch. Os FDWs do PostgreSQL exigem esse mapeamento de usuário para funcionar. O AlloyDB faz a autenticação usando o cabeçalho de autorização REST.

    CREATE USER MAPPING FOR CURRENT_USER
           SERVER ELASTICSEARCH_SERVER_NAME;
    
  4. Configure o esquema dos dados do Elasticsearch usando uma tabela de dados externos.

    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');
    

    Substitua as seguintes variáveis novas:

    • ELASTICSEARCH_FD_TABLE: nome da tabela de dados externa que representa sua tabela do Elasticsearch. Por exemplo, my-fd-elasticsearch-table.

    • ELASTICSEARCH_FIELDS: lista separada por vírgulas de definições de esquema de campo do Elasticsearch no seguinte formato: elasticsearch_field_name PG_DATA_TYPE. Por exemplo, elasticsearch_boolean_field_name BOOLEAN, elasticsearch_double_field_name DOUBLE PRECISION. Esses campos precisam corresponder aos nomes de campo no Elasticsearch, a menos que a opção remote_field_name seja anexada. Por exemplo, elasticsearch_foo OPTIONS (remote_field_name 'elasticsearch_FOO').

      Para ver a lista de tipos de dados do Elasticsearch que podem ser definidos para o AlloyDB, consulte Tipos de dados compatíveis.

    • ELASTICSEARCH_INDEX_NAME: nome do índice do Elasticsearch. Por exemplo, my-elasticsearch-index.

Tipos de dados compatíveis

O AlloyDB é compatível com os seguintes tipos de dados do Elasticsearch:

Tipos de dados Tipo PostgreSQL
alias Tipo do PostgreSQL para o campo que alias está referenciando
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

Consultar os dados do Elasticsearch

O AlloyDB recebe consultas SQL e as converte em consultas da API REST do Elasticsearch. Durante essa conversão, o AlloyDB tenta enviar o máximo possível de lógica de consulta sem alterar a identidade da consulta, incluindo o LIMIT da consulta SQL. No entanto, há casos em que você pode especificar que determinados campos do Elasticsearch não sejam enviados ou em que a lógica de consulta não pode ser enviada. Por exemplo, LIKE e outros operadores de correspondência de texto não podem ser enviados. Para mais exemplos do que pode e não pode ser enviado, consulte Exemplos de envio.

Em cenários em que LIMIT é definido como maior que pagination_num_results ou em que LIMIT não é especificado ou não pode ser enviado, o AlloyDB usa a API Scroll, que pode consumir muitos recursos.

Como a API Scroll pode consumir muitos recursos, recomendamos examinar suas consultas usando EXPLAIN VERBOSE para ver quais APIs são usadas. Limitar o uso da API Scroll e usar LIMIT melhora o desempenho.

Para consultar seus dados do Elasticsearch, você tem as seguintes opções:

  • Consultas SQL padrão
  • DSL de consulta
  • Pesquisas híbridas

Consultas SQL padrão

As consultas SQL padrão podem ser escritas usando a sintaxe Lucene do Elasticsearch.

Para realizar uma consulta SQL padrão, confira o exemplo a seguir:

SELECT id, body
FROM ELASTICSEARCH_FD_TABLE
WHERE FILTER
ORDER BY metadata <@> 'QUERY';

Substitua as seguintes variáveis:

  • ELASTICSEARCH_FD_TABLE: nome da tabela de dados externa que representa sua tabela do Elasticsearch. Por exemplo, my-fd-elasticsearch-table.

  • (Opcional) FILTER: filtro a ser aplicado à consulta do Elasticsearch. Por exemplo, AND qubits < 105.

  • QUERY: consulta a ser enviada ao Elasticsearch. Confira alguns exemplos de consultas na lista a seguir:

    • body:quantum body:computing
    • body:(quantum computing)
    • body:(quantum AND computing)
    • body:"quantum computing"
    • body:"quantum computing" AND qubits:[* TO 105}

DSL de consulta

A DSL de consulta é a linguagem de consulta completa do Elasticsearch, no estilo JSON, recomendada para casos de uso avançados. A DSL de consulta permite realizar pesquisas, filtragens e agregações complexas que não podem ser expressas na sintaxe de consulta SQL.

Para realizar consultas usando a DSL de consulta, confira o exemplo a seguir:

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;

Substitua as seguintes variáveis:

  • ELASTICSEARCH_FD_TABLE: nome da tabela de dados externa que representa sua tabela do Elasticsearch. Por exemplo, my-fd-elasticsearch-table.

  • QUERY: consulta a ser enviada ao Elasticsearch. Por exemplo, "elasticsearch_field_name:\"quantum computing\" OR int_field:[* TO 3]".

Para a DSL de consulta, é necessário propagar apenas as expressões query, filter e sort.

Para realizar uma pesquisa híbrida nos dados do Elasticsearch, consulte o exemplo de pesquisa a seguir:

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;

Substitua as seguintes variáveis:

  • LIMIT: número de resultados a serem retornados. Por exemplo, 3.

  • WEIGHT: contribuição dessa entrada de pesquisa para a Reciprocal Rank Fusion (RRF) geral.

  • ELASTICSEARCH_FD_TABLE: nome da tabela de dados externa que representa sua tabela do Elasticsearch. Por exemplo, my-fd-elasticsearch-table.

  • DOCUMENT_ID_COLUMN_NAME: nome da coluna de ID do documento.

  • QUERY: consulta a ser enviada ao Elasticsearch. Por exemplo, "elasticsearch_field_name:\"quantum computing\"" pesquisa a frase "computação quântica" no campo elasticsearch_field_name. Todos os tipos de consulta mencionados em Tipos de dados compatíveis podem ser usados na sua consulta.

Para mais informações sobre os parâmetros disponíveis para pesquisas híbridas, consulte Parâmetros da função de pesquisa híbrida.

Exemplos de pushdown

Para tornar as consultas mais eficientes, o AlloyDB tenta enviar os seguintes aspectos da consulta diretamente para a chamada de API feita ao Elasticsearch:

  • SELECT campos
  • WHERE filtros
  • ORDER BY tipos
  • LIMIT

Para ver exemplos de consultas que ilustram quais aspectos o AlloyDB pode ou não enviar, consulte a tabela a seguir.

Tipo de consulta Exemplo de consulta Elementos de consulta enviados
Consultas não filtradas
SELECT id, body
FROM elasticsearch_table
ORDER BY metadata <@> 'body:foo' DESC
LIMIT 10;
  • SELECT campos
  • ORDER BY ... DESC classificação
  • LIMIT
Correspondência exata de texto
SELECT id, body
FROM elasticsearch_table
WHERE body = 'foo'
LIMIT 10;
  • SELECT campos
  • WHERE filtro
  • LIMIT
Expressões de campo único
SELECT id, body
FROM elasticsearch_table
WHERE id > 10
ORDER BY metadata <@> 'body:foo'
LIMIT 10;
  • SELECT campos
  • WHERE filtro
Expressões constantes
SELECT id, body
FROM elasticsearch_table
WHERE id > (1+1)
LIMIT 10;
  • SELECT campos
  • WHERE filtro
  • LIMIT
Expressões com funções
SELECT id, body
FROM elasticsearch_table
WHERE id > CEIL(3.14)
LIMIT 10;
  • SELECT campos
Expressões de vários campos
SELECT id, body
FROM elasticsearch_table
WHERE dbl_field < flt_field
LIMIT 10;
  • SELECT campos
Filtragem de pontuação
SELECT id, body, (metadata <@> 'body:bar') AS score
FROM elasticsearch_table
WHERE score > 0.5
ORDER by score desc
LIMIT 10;
  • SELECT campos
  • ORDER BY ... DESC classificação
LIKE e operadores semelhantes
SELECT id, body
FROM elasticsearch_table
WHERE id > 10 AND body LIKE '%foo%'
LIMIT 10;
  • SELECT campos
  • WHERE id > 10 filtro
Consultas brutas
SELECT id, body
FROM elasticsearch_table
WHERE id < 10
ORDER BY metadata <@> $${"query": { "match_all": {}}}$$ DESC
LIMIT 10;
  • SELECT campos
  • ORDER BY ... DESC classificação

Solução de problemas

Se você tiver problemas de autenticação ou conectividade ao consultar o cluster do Elasticsearch, verifique as seguintes causas comuns:

  • Erros de autenticação HTTP 401 ou 403: verifique se o secret do Elasticsearch no Secret Manager contém credenciais de autenticação válidas para o auth_method (ApiKey ou Basic) e se a conta de serviço usada pelo AlloyDB tem a permissão secretmanager.secretAccessor.
  • Tempo limite de conexão: verifique se a conectividade de IP público de saída está ativada na instância principal do AlloyDB e se o firewall do Elasticsearch permite conexões de entrada na porta especificada.

Limitações

Antes de conectar o AlloyDB ao Elasticsearch, esteja ciente das seguintes limitações:

  • A integração com o Elasticsearch só está disponível na versão principal 17 e mais recentes do PostgreSQL.

  • O AlloyDB lê, mas não grava, dados do Elasticsearch.

  • Você é responsável por sincronizar dados entre o AlloyDB e o Elasticsearch.

  • Tipos especializados do Elasticsearch, como geo_point, não são compatíveis. Para ver a lista completa de tipos de dados compatíveis, consulte Tipos de dados compatíveis.

A seguir