Carga datos geográficos en Elasticsearch con GDAL

¿Todavía no has probado Elastic Maps en Kibana? El soporte para múltiples capas es espectacular: mapas de calor, capas vectoriales, capas del Elastic Maps Service, e incluso documentos individuales, ¡todo en una misma interfaz! Qué gran manera de analizar y visualizar tus datos ¿verdad?

¿Pero qué pasa con los datos geográficos que no están todavía en Elasticsearch? Por ejemplo, tal vez quieras hacer agregaciones sobre un shapefile de territorios de ventas, o tal vez tengas un fichero CSV con las localizaciones de tus centros de distribución. Quieres tener estos datos en Elasticsearch, pero configurar Filebeat o Logstash no es lo más adecuado para datasets estáticos. Bien, pues tenemos la solución ideal para ti: GDAL.

GDAL (Geospatial Data Abstraction Library) contiene herramientas de línea de comandos para convertir datos geográficos en más de 70 formatos diferentes, incluyendo por supuesto Elasticsearch. GDAL puede compilarse desde su código fuente o instalarse mediante gestores de paquetes. También puede instalarse via Homebrew OSGeo para Mac (ejecutando brew tap osgeo/osgeo4mac && brew install osgeo-gdal). Una nota importante, es necesario instalar GDAL v3.1 o posterior para poder cargar datos en Elasticsearch 7.x.

Conectar con Elasticsearch

Una vez GDAL está instalada, puedes abrir un terminal de comandos e intentar conectar con tu cluster de Elasticsearch usando el comando ogrinfo. Se emplea el prefijo "ES:" para indicar que queremos usar el driver para Elasticsearch.

ogrinfo ES:http://localhost:9200

Si tu cluster tiene la seguridad activada (buena idea), debes añadir un usuario y contraseña válidos al principio de la IP o el dominio usando el formato usuario:contraseña@. Por ejemplo:

ogrinfo ES:https://usuario:contraseña@example.com:9243

Este comando imprimirá una lista de los índices de tu cluster, así como el tipo de geometría asociado, si es que existe.

Es posible almacenar las credenciales en un fichero .netrc en tu carpeta de usuario. GDAL utiliza curl para conectar a Elasticsearch, y las credenciales se toman automáticamente desde este fichero. Usando el ejemplo anterior, mi fichero .netrc sería:

machine example.com
login usuario
password contraseña

Y el comando para GDAL sería ahora:

ogrinfo ES:https://example.com:9243

Cargar un shapefile en Elasticsearch

Ahora que has confirmado que puedes conectar con Elasticsearch, puedes probar a cargar un shapefile. Un shapefile es un formato de fichero binario que contiene geometrías y atributos. La manera más rápida de cargar un shapefile en Elasticsearch es usando la herramienta ogr2ogr.

ogr2ogr ES:http://localhost:9200 my_shapefile.shp

Por otro lado, los valores por defecto de GDAL pueden no ser los ideales para tus datos. Por ejemplo, GDAL asume que todos tus atributos serán mapeados en Elasticsearch como de tipo "texto", indexados para búsquedas de texto libre. Es habitual que muchos de esos campos deban ser mapeados como tipo "keyword" para poder usarlos en agregaciones. Para marcarlos todos de esta manera se puede pasar el modificador -lco NOT_ANALYZED_FIELDS={ALL}, o bien pasar una lista de campos separada por comas en lugar de {ALL}.

Otra opción interesante es pasar nuestro propio fichero de mappings para la carga en Elasticsearch. Por suerte no tenemos que crear el fichero manualmente, ya que GDAL puede generar uno para nosotros automáticamente. Usaremos de nuevo la herramienta ogr2ogr, añadiendo algunos parámetros más para generar nuestro mapping. Esto simplemente generará el fichero, sin realizar ninguna operación de carga en nuestro cluster.

ogr2ogr -lco INDEX_NAME=gdal-data -lco NOT_ANALYZED_FIELDS={ALL} -lco WRITE_MAPPING=./mapping.json ES:http://localhost:9200 my_shapefile.shp

Tras ejecutar el comando el fichero mapping.json queda listo para adaptarlo con cualquier editor de texto. Una vez configurado para nuestras necesidades, podemos referenciarlo para cargar por fin nuestro shapefile.

ogr2ogr -lco INDEX_NAME=gdal-data -lco OVERWRITE_INDEX=YES -lco MAPPING=./mapping.json ES:http://localhost:9200 my_shapefile.shp

GDAL y mapping types

GDAL dispone de un parámetro MAPPING_NAME que puede especificarse para versiones anteriores de Elasticsearch que soportan mapping types. Si estás usando Elasticsearch 6 o anteriores, el mapping type por defecto es "FeatureCollection" y cada documento tendrá sus atributos en un campo anidado denominado "properties". Actualmente Kibana no soporta campos anidados, por lo que recomendados encarecidamente cambiar el parámetro MAPPING_NAME a un valor como por ejemplo "doc" que no utiliza campos anidados. Este parámetro no tiene efecto en Elasticsearch 7 y posteriores porque los mapping types fueron eliminados.

ogr2ogr -lco MAPPING_NAME=doc -lco INDEX_NAME=gdal-data -lco MAPPING=./mapping.json ES:http://localhost:9200 my_shapefile.shp

Más recursos

GDAL es una herramienta tremendamente potente y encontrar las opciones correctas para cada comando requiere de la revisión de la documentación del driver y bastantes pruebas. La documentación del comando ogr2ogr es muy importante y debe revisarse en detalle, así como la documentación de cada driver de entrada y salida, ya que cada uno tiene sus propias opciones de configuración.

La web BostonGIS.com dispone de una buena receta para ogr2ogr que puede ser de utilidad. Existen algunas más en GitHub. He creado igualmente una lista de ejemplos de comandos para la carga de datos geográficos en Elasticsearch desde distintos formatos. Si lo deseas, puedes probarlos con una versión de prueba de nuestro servicio de Elasticsearch. Y mientras haces esto, si no lo has hecho aún, ¡no te olvides de probar Elastic Maps!

Si te encuentras con cualquier problema, recuerda que dispones de los foros de discusión de Elastic y de https://gis.stackexchange.com/. ¡Que te diviertas!