Dec 15th, 2023: [ES] Haciendo mapas navideños con Elasticsearch y MapLibre

Este artículo está también disponible en Inglés

Introducción

Una de las sugerencias de seguridad más habituales relacionadas con Elasticsearch es que nunca debes exponer tu clúster en Internet. Pero como estamos en la época navideña, y nos gusta un poquito la juerga, vamos a proponer un pequeño ejercicio técnico accediendo a nuestro motor de búsquedas y base de datos favorita directamente desde el navegador para nada menos que pintar unos mapas bonicos.

Como tal vez sepas, Elasticsearch puede representar gran cantidad de datos geoespaciales gracias a las teselas vectoriales. Si no sabes de lo que hablo te invito a echar un vistazo a este espectacular artículo de Ignacio y Thomas.

Al igual que muchos otros endpoints de Elasticsearch, la API de Vector Tiles espera un objeto JSON en el que definir consultas y agregaciones arbitrariamente complejas. Pero las bibliotecas de webmapping no funcionan así, ya que esperan como parámetro la URL de un servidor con una plantilla para el nivel de zoom y las coordenadas X e Y, más o menos así: https://my-server/tiles/${z}/${x}/${y}. La aproximación clásica (por esta y muchas otras razones) es implementar un middleware que se encargará de construir las consultas correctas, haciendo de fachada para Elasticsearch. De esta forma, las aplicaciones cliente en el navegador harán peticiones GET normales sin saber nada del backend.


Diagrama secuencia con la aproximación habitual para pintar teselas vectoriales.

Si estás aprendiendo sobre Elasticsearch, o construyendo algo sencillo, o simplemente jugando un poco, tal vez te interese quitarte de en medio ese middleware y conseguir que tu navegador hable directamente con tu base de datos. ¿Pero cómo?

MapLibre es una popular biblioteca de webmapping que aprovecha las últimas tecnologías web para representar datos desde teselas vectoriales con mapas base espectaculares. Es lo que usamos en Kibana Maps y nos encanta el proyecto y su comunidad. La biblioteca tiene una curiosa funcionalidad que permite capturar las peticiones de teselas y modificarlas a voluntad, cambiando el verbo HTTP de GET a POST, las cabeceras, y hasta añadir un payload personalizado, así que ¡venga vamos a usar esto!


Diagrama secuencia con la aproximación navideña-YOLO.

Datos

La Overture Maps Foundation es un esfuerzo coordinado entre Microsoft, Meta, Esri, y otros para recoger y publicar grandes juegos de datos en abierto. Para este ejercicio he subido a un clúster el tema de lugares de interés de Overture 2023-07-26-alpha.0 , con más de 59 millones de localizaciones en todo el mundo proporcionadas por Meta y Microsoft.

Puedes echar un vistazo al juego de datos en este tablero de Kibana.


Tablero con puntos de interés de la Overture Maps Foundation.

Preparando Elasticsearch

Para acceder a estos datos desde el navegador, primero tenemos que configurar el clúster para establecer las cabeceras CORS, tal y como detallé en la sección de preparación de datos del taller de Elasticsearch geospacial. A continuación hay que crear una API key para acceder con permisos de sólo-lectura al índice overture-places tanto para consultas normales como de teselas vectoriales.

Truco
Si estás siguiendo el taller mejor no cierres tu ventana de Kibana porque te va a resultar muy útil para explorar los datos: ver los campos disponibles, su dominio, etc.

Mostrando localizaciones navideñas

He dejado en el repositorio de Github jsanz/advent-2023 algo de código para este artículo. Se puede previsualizar en https://jsanz.github.io/advent-2023 y no puede ser más simple: un HTML y un fichero con un módulo JavaScript. Como mapa base para este ejemplo he elegido MapTiler y su estilo winter.


Por defecto se muestran los puntos con el texto "Santa Claus".

El código interesante se encuentra al principio de app.js, donde podemos encontrar las constantes que detallan la localización del clúster de Elasticsearch, la API key, y finalmente la función getDynamicTransformRequest . Al crear el objeto para el mapa un poco más abajo, en el parámetro transformRequest se le pasa esta función para que transforme las peticiones. Esta función va a comprobar que el recurso solicitado es de Elasticsearch, y le va a adjuntar una consulta de búsqueda, así como la cabecera de autenticación.

const getDynamicTransFormRequest = function (url, resourceType) {
  /* This function enriches the HTTP request to include
              the ES search body, change to a POST request, and include
              the Content-Type header */
  if (resourceType == "Tile" && url.startsWith(ES_HOST)) {
    const query = document.getElementById("search").value || DEFAULT_QUERY;
    
    /* Build a VT query payload */
    const body = {
      grid_precision: 0,
      exact_bounds: true,
      extent: 4096,
      fields: ["name", "category_main", "category_alt", "source", "social"],
      query: {
        bool: {
          filter: [
            {
              multi_match: {
                lenient: true,
                query: `*${query}*`,
                type: "phrase",
              },
            },
          ],
        },
      },
    }

    return {
      url: url,
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `ApiKey ${ES_APIKEY}`,
      },
      body: JSON.stringify(body),
    };
  }
};

[...]

const map = new maplibregl.Map({
    container: "map",
    style,
    center: [0, 15],
    zoom: 1,
    hash: true,
    transformRequest: getDynamicTransFormRequest,
});

El resto del script es código estándar de MapLibre para hacer un mapa temático por tipo de localización, adjuntando un pequeño pop up para que al pulsar sobre un punto se nos muestre un poco más de detalle sobre el mismo.


Las tiendas de árboles de Navidad son bastante populares en la costa este de los Estados Unidos.

Truco
Prueba a abrir la consola de desarrollo de tu navegador para echar un vistazo a las peticiones de red a Elasticsearch

En la primera carga la página hace una búsqueda a la base de datos por localizaciones que tengan "Santa Claus". He dejado algunas sugerencias de búsqueda en el formulario, pero te animo a dejar volar tu imaginación y buscar otras localizaciones navideñas interesantes.


¡Hari Natal todo el mundo!

Para ir más allá

Este ejercicio es en realidad el primer paso del taller sobre Elasticsearch geoespacial. Te invito a seguir el resto de lecciones para aprender a escribir consultas y representar datos espaciales tanto como documentos individuales, como mucho más interesante, en forma de agregaciones para resumir y analizar grandes volúmenes de datos usando nuestras agregaciones en hexágonos, por ejemplo.


Mapa de datos del servicio 311 de Nueva York agregado en hexágonos.

Truco
Si no quieres o no te apetece hacer el taller completo pero te gustaría jugar con los mapas, puedes visitar https://webmapping-elasticsearch-2023.glitch.me donde encontrarás un despliegue de los ejercicios.

Una sugerencia final: la herramienta Inspect de Kibana es increíblemente útil cuando desarrollas aplicaciones para Elasticsearch y está también disponible para Maps. Te recomiendo usarla para aprender cómo Kibana mezcla todos los filtros de los diferentes elementos de la interfaz como la barra de búsqueda y las píldoras de los filtros para producir la petición final que se envía a la base de datos.


La herramienta para inspeccionar consultas de Kibana Maps.

Conclusión

Gracias a este pequeño truco con MapLibre presentado aquí podemos explorar y aprender el lenguaje de consultas de Elasticsearch con un bucle de interacción y desarrollo muy rápido: actualiza tu consulta o tu código de renderizado y recarga tu ventana del navegador :boom:. También da unas pinceladas sobre las estupendas capacidades geoespaciales de Elasticsearch para casos de uso con muchísimos datos.

:santa::christmas_tree: ¡¡Felices Fiestas!! :christmas_tree::santa:

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.