En este tutorial vamos a analizar la posibilidad de realizar modificaciones parciales en los documentos almacenados en Elasticsearch.
Índice de contenidos
- 1. Introducción
- 2. Entorno
- 3. Modificación parcial de un único registro en Elasticsearch
- 4. Automatizar la modificación de registros con Python
- 5. Código fuente del tutorial
- 6. Conclusiones
1. Introducción
A modo de introducción previa al tutorial os dejo dos estupendos tutoriales sobre Elasticsearch y Kibana ya que el contenido está enfocado a desarrolladores con conocimientos previos sobre las tecnologías mencionadas.
Primero vamos a explicar cómo realizarlas a través de las herramientas de administración de Kibana para luego automatizarlas con un script en Python.
Para el tutorial vamos a suponer que necesitamos actualizar el campo “number” del documento “bill”. Solo queremos modificar aquellos documentos cuyo “number” tenga 8 dígitos y truncarlos a 7 por la derecha.
2. Entorno
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil MacBook Pro 15′ (2.5 GHz Intel Core i7, 16GB DDR3, 500GB Flash Storage).
- Sistema Operativo: Mac OS Sierra 10.12.3
- Entorno de desarrollo: Atom 1.14.2
- Elasticsearch 5.0.1
- Kibana 5.0.0
- Python 2.7.13 con requests 2.13.0
3. Modificación parcial de un único registro en Elasticsearch
Para empezar analizaremos la llamada al API de Elasticsearch para actualizar un único registro a través de las herramientas de desarrollador de Kibana:
POST store/bill/20170124103200000000066666660012066361239/_update { "doc": { "details": { "number": "1234567" } } }
En la URL nos encontramos los siguientes parámetros:
store/bill/20170124103200000000066666660012066361239/_update
- store: índice del registro
- bill: tipo de registro
- 20170124103200000000066666660012066361239: identificador único del registro
- _update: acción a realizar sobre el registro
Se puede observar que el documento contiene únicamente los campos que queremos actualizar, en este caso el número de la factura.
Con esta llamada, solo el “number” es actualizado pero la política de Elasticsearch es reemplazar los documentos completamente por lo que internamente borrará el registro, hará los cambios indicados e insertará de nuevo el documento.
4. Automatizar la modificación de registros con Python
Elasticsearch tiene un API para Python para realizar operaciones pero en este caso vamos a prescindir de él ya que con comandos básicos de Python podemos conseguir nuestro objetivo.
elasticsearch_query = '{"query":{"bool":{"must":{"match":{"type":"bill"}}, "filter":{"regexp":{"details.number":{"value":"[0-9]{8}"}}}}}}' elasticsearch_query_response = requests.get(elasticsearch_url + '_search', data = elasticsearch_query)
Si Elasticsearch nos devuelve resultados, los almacenaremos en un array para más tarde actualizar los registros obtenidos. Podemos realizar el almacenaje de la siguiente manera:
for hit in elasticsearch_response.json()['hits']['hits']: elastic_search_records.append( entities.ElasticSearchRecord(hit['_index'], hit['_id'], hit['_source']['details']['number']) )
Por último y para realizar las modificaciones en Elasticsearch, recorreremos el array donde hemos almacenado la información de los registros obtenidos e invocaremos la siguiente llamada:
elasticsearch_url_update= elasticSearchRecord.index + '/bill/' + elasticSearchRecord.id elasticsearch_data_update='{"doc":{"details":{"number":"'+elasticSearchRecord.number[:7]+'"}}}' elasticsearch_update_response= requests.post(elasticsearch_url+elasticsearch_url_update+'/_update', data= elasticsearch_data_update)
Esto hará que se actualice la información en Elasticsearch y nos devolverá un error en caso de que no se pueda actualizar el registro o algún parámetro sea incorrecto.
Como he explicado anteriormente, aunque solo se actualiza el documento parcialmente, Elasticsearch reemplaza los documentos completamente por lo que si los parámetros o los datos enviados son erróneos podríamos llegar a sobreescribir el documento por completo.
5. Código fuente del tutorial
En mi repositorio de GitHub podéis encontrar todo el código del proyecto del tutorial. Para ejecutarlo solo hay que tener instalado el entorno que he indicado y ejecutar el siguiente comando en un terminal “python partials_modifications.py”.
6. Conclusiones
Esta solución es poco efectiva desde el punto de vista del número de llamadas que se realizan a Elasticsearch y se puede solucionar en una sola llamada con el método “Update by query” en el que se hace la query y la actualización en un solo paso.
Pero si el campo a actualizar tuviera una fuente de datos externa a Elasticsearch o el cambio no se pudiera realizar con el parámetro “script”, la solución analizada en este tutorial nos aportaría más flexibilidad.
Un saludo.
Alejandro