Accede a los datos de Elasticsearch desde AlloyDB para PostgreSQL

Accede a los datos almacenados en Elasticsearch y búscalos creando un wrapper de datos externos (FDW) y una tabla externa en AlloyDB para PostgreSQL.

Limitaciones

Antes de conectar AlloyDB a Elasticsearch, ten en cuenta las siguientes limitaciones:

  • La integración de Elasticsearch solo está disponible en la versión principal 17 de PostgreSQL y versiones posteriores.

  • AlloyDB lee los datos de Elasticsearch, pero no escribe en ellos.

  • Eres responsable de sincronizar los datos entre AlloyDB y Elasticsearch.

  • No se admiten tipos especializados de Elasticsearch, como geo_point. Para obtener la lista completa de los tipos de datos admitidos, consulta Tipos de datos admitidos.

Antes de comenzar

Antes de comenzar, asegúrate de haber completado los siguientes pasos:

Almacena la clave de API de Elasticsearch en Secret Manager

AlloyDB almacena y lee tu clave de API de Elasticsearch desde Secret Manager. Para obtener más información sobre cómo usar Secret Manager, consulta Crea un secreto y accede a él con Secret Manager.

Asegúrate de otorgarle permiso a tu cuenta de servicio de AlloyDB para leer el secreto. Para obtener más información, consulta Crea un secreto y accede a él con Secret Manager.

Habilita y configura la extensión de external_search_fdw

Para comenzar la integración con Elasticsearch, completa las siguientes instrucciones para habilitar y configurar la extensión external_search_fdw de AlloyDB:

  1. Habilita la extensión external_search_fdw.

    CREATE EXTENSION external_search_fdw;
    
  2. Configura el acceso a tu clúster de Elasticsearch a través de un servidor de datos 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');
    

    Reemplaza las siguientes variables:

    • ELASTICSEARCH_SERVER_NAME: Nombre de tu servidor de datos externos. Por ejemplo, my-elasticsearch-server.

    • ELASTICSEARCH_SERVER_HOST_PORT: URL pública de tu clúster de Elasticsearch. Por ejemplo, https://node1.elastic.test.com:9200.

    • AUTH_METHOD: Es el tipo de autenticación que se usará. Puedes elegir entre las siguientes opciones:

    • SECRET_PATH: Ruta de Secret Manager a tus credenciales de autenticación de Elasticsearch. Por ejemplo, projects/123456789012/secrets/apikey/versions/1. 123456789012 representa el ID de tu proyecto de Google Cloud .

    • (Opcional) MAX_DEADLINE: Es la cantidad máxima de tiempo, en milisegundos, que AlloyDB espera una respuesta de Elasticsearch. Debes establecer este valor según las ubicaciones de tus instancias de AlloyDB y Elasticsearch. El valor predeterminado es 10000.

    • PAGINATION_NUM_RESULTS (opcional): Cantidad máxima de resultados recuperados por lote de Elasticsearch. Si se solicitan más resultados, AlloyDB los recupera en varios lotes de este tamaño. El valor predeterminado es 32.

    • PAGINATION_CONTEXT_TIMEOUT: Cantidad de tiempo, en milisegundos, que Elasticsearch mantiene activo el contexto de la solicitud de paginación (opcional). El valor predeterminado es 30000.

  3. Define la asignación de usuarios de PostgreSQL para el servidor de Elasticsearch. Ten en cuenta que los FDW de PostgreSQL requieren esta asignación de usuarios para funcionar. AlloyDB se autentica con el encabezado de autorización de REST.

    CREATE USER MAPPING FOR CURRENT_USER
           SERVER ELASTICSEARCH_SERVER_NAME;
    
  4. Configura el esquema de tus datos de Elasticsearch a través de una tabla de datos externa.

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

    Reemplaza las siguientes variables nuevas:

    • ELASTICSEARCH_FD_TABLE: Nombre de la tabla de datos externa que representa tu tabla de Elasticsearch. Por ejemplo, my-fd-elasticsearch-table

    • ELASTICSEARCH_FIELDS: Es una lista separada por comas de definiciones de esquema de campos de Elasticsearch en el siguiente formato: elasticsearch_field_name PG_DATA_TYPE. Por ejemplo, elasticsearch_boolean_field_name BOOLEAN, elasticsearch_double_field_name DOUBLE PRECISION. Estos campos deben coincidir con los nombres de los campos en Elasticsearch, a menos que se agregue la opción remote_field_name. Por ejemplo: elasticsearch_foo OPTIONS (remote_field_name 'elasticsearch_FOO').

      Para obtener la lista de los tipos de datos de Elasticsearch que se pueden definir para AlloyDB, consulta Tipos de datos admitidos.

    • ELASTICSEARCH_INDEX_NAME: Es el nombre de tu índice de Elasticsearch. Por ejemplo, my-elasticsearch-index

Tipos de datos admitidos

AlloyDB admite los siguientes tipos de datos de Elasticsearch:

Tipos de datos Tipo de PostgreSQL
alias Tipo de PostgreSQL para el campo al que hace referencia alias
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

Consulta tus datos de Elasticsearch

AlloyDB toma las consultas en SQL y las convierte en consultas de la API de REST de Elasticsearch. Durante esta conversión, AlloyDB intenta insertar la mayor cantidad posible de lógica de consulta sin cambiar la identidad de la consulta, incluido el LIMIT de la consulta en SQL. Sin embargo, hay casos en los que es posible que especifiques que no se envíen ciertos campos de Elasticsearch o en los que no se pueda enviar la lógica de la consulta. Por ejemplo, no se pueden enviar los operadores de coincidencia de texto, como LIKE, hacia abajo. Para obtener más ejemplos de lo que se puede y no se puede enviar, consulta Ejemplos de envío.

En situaciones en las que LIMIT se establece en un valor superior a pagination_num_results o en las que LIMIT no se especifica o no se puede enviar, AlloyDB usa la API de Scroll, que puede consumir muchos recursos.

Dado que la API de Scroll puede consumir muchos recursos, te recomendamos que examines tus consultas con EXPLAIN VERBOSE para ver qué APIs se usan. Limitar el uso de la API de Scroll y usar LIMIT mejora el rendimiento.

Para consultar tus datos de Elasticsearch, tienes las siguientes opciones:

  • Consultas de SQL estándar
  • DSL de consultas
  • Búsquedas híbridas

Consultas de SQL estándar

Las consultas en SQL estándar se pueden escribir con la sintaxis de Lucene de Elasticsearch.

Para realizar una consulta en SQL estándar, consulta el siguiente ejemplo:

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

Reemplaza las siguientes variables:

  • ELASTICSEARCH_FD_TABLE: Nombre de la tabla de datos externa que representa tu tabla de Elasticsearch. Por ejemplo, my-fd-elasticsearch-table.

  • FILTER: Es el filtro que se aplicará a tu búsqueda de Elasticsearch (opcional). Por ejemplo, AND qubits < 105

  • QUERY: Es la consulta que se enviará a Elasticsearch. Para ver algunos ejemplos de consultas, consulta la siguiente lista:

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

DSL de consultas

El lenguaje de consulta específico del dominio (DSL) de consultas es el lenguaje de consulta con todas las funciones y estilo JSON de Elasticsearch que se recomienda para casos de uso avanzados. El DSL de consultas te permite realizar búsquedas, filtrados y agregaciones complejos que no se pueden expresar en la sintaxis de consulta en SQL.

Para realizar consultas con el DSL de consultas, consulta el siguiente ejemplo de consulta:

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;

Reemplaza las siguientes variables:

  • ELASTICSEARCH_FD_TABLE: Nombre de la tabla de datos externa que representa tu tabla de Elasticsearch. Por ejemplo, my-fd-elasticsearch-table.

  • QUERY: Es la consulta que se enviará a Elasticsearch. Por ejemplo, "elasticsearch_field_name:\"quantum computing\" OR int_field:[* TO 3]".

Ten en cuenta que, para el DSL de consultas, solo se espera que propagues las expresiones query, filter y sort.

Para realizar una búsqueda híbrida en tus datos de Elasticsearch, consulta el siguiente ejemplo de búsqueda:

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;

Reemplaza las siguientes variables:

  • LIMIT: Es la cantidad de resultados que se devolverán. Por ejemplo, 3

  • WEIGHT: Contribución de esta entrada de búsqueda a la combinación de clasificación recíproca (RRF) general.

  • ELASTICSEARCH_FD_TABLE: Nombre de la tabla de datos externa que representa tu tabla de Elasticsearch. Por ejemplo, my-fd-elasticsearch-table.

  • DOCUMENT_ID_COLUMN_NAME: Nombre de la columna del ID del documento.

  • QUERY: Es la consulta que se enviará a Elasticsearch. Por ejemplo, "elasticsearch_field_name:\"quantum computing\"" busca la frase "computación cuántica" en el campo elasticsearch_field_name. En tu búsqueda, puedes usar todos los tipos de consultas que se mencionan en Tipos de datos admitidos.

Para obtener más información sobre los parámetros disponibles para las búsquedas híbridas, consulta Parámetros de la función de búsqueda híbrida.

Ejemplos de envío de datos

Para que las consultas sean más eficientes, AlloyDB intenta enviar los siguientes aspectos de la consulta directamente a la llamada a la API que se realiza a Elasticsearch:

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

Para ver ejemplos de consultas que ilustran qué aspectos AlloyDB puede y no puede enviar, consulta la siguiente tabla.

Tipo de consulta Ejemplo de consulta Elementos de la consulta enviados hacia abajo
Consultas sin filtrar
SELECT id, body
FROM elasticsearch_table
ORDER BY metadata <@> 'body:foo' DESC
LIMIT 10;
  • SELECT campos
  • ORDER BY ... DESC ordenar
  • LIMIT
Coincidencia de texto exacto
SELECT id, body
FROM elasticsearch_table
WHERE body = 'foo'
LIMIT 10;
  • SELECT campos
  • WHERE filtro
  • LIMIT
Expresiones de campo único
SELECT id, body
FROM elasticsearch_table
WHERE id > 10
ORDER BY metadata <@> 'body:foo'
LIMIT 10;
  • SELECT campos
  • WHERE filtro
Expresiones constantes
SELECT id, body
FROM elasticsearch_table
WHERE id > (1+1)
LIMIT 10;
  • SELECT campos
  • WHERE filtro
  • LIMIT
Expresiones con funciones
SELECT id, body
FROM elasticsearch_table
WHERE id > CEIL(3.14)
LIMIT 10;
  • SELECT campos
Expresiones de varios campos
SELECT id, body
FROM elasticsearch_table
WHERE dbl_field < flt_field
LIMIT 10;
  • SELECT campos
Filtrado de puntuaciones
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 ordenar
LIKE y operadores similares
SELECT id, body
FROM elasticsearch_table
WHERE id > 10 AND body LIKE '%foo%'
LIMIT 10;
  • SELECT campos
  • WHERE id > 10 filtro
Consultas sin procesar
SELECT id, body
FROM elasticsearch_table
WHERE id < 10
ORDER BY metadata <@> $${"query": { "match_all": {}}}$$ DESC
LIMIT 10;
  • SELECT campos
  • ORDER BY ... DESC ordenar