Elasticsearch ha sido un chico genial en la ciudad durante bastante tiempo en lo que respecta a la búsqueda de texto completo. Muchas empresas como Uber, Slack, Udemy, etc. lo utilizan para la búsqueda. Hay muchas más ventajas de Elasticsearch además de la búsqueda de texto completo, como herramientas poderosas para el análisis de datos para escalar con facilidad. Vivimos en una era en la que los datos fluyen como cualquier cosa, y los datos en el sistema a menudo cambian con los requisitos. Es posible que nos encontremos con situaciones en las que necesitemos actualizar o modificar los datos.
En este artículo, vamos a actualizar los documentos en Elasticsearch de la siguiente manera:
- Agregar un nuevo campo en todos los registros.
- Actualizar un campo en condición.
- Agregar un campo en condición.
- Eliminar un campo.
- Eliminar un campo bajo condición.
Para actualizar los datos, vamos a utilizar un lenguaje de scripting especialmente diseñado para Elasticsearch, Painless.
Para realizar las operaciones mencionadas anteriormente, usaremos Kibana.
1. Crear índice
Para insertar y actualizar datos, primero tendremos que crear un índice sobre el que realizaremos todas nuestras operaciones. Para hacerlo, siga la siguiente declaración:
Syntax : PUT /employee
La consulta anterior va a crear un índice vacío (llamado empleado). Después de crear el índice con éxito, insertaremos algunos registros en el índice de empleados .
2. Insertar datos.
Antes de insertar los datos, echemos un vistazo a la estructura de un documento. A continuación se muestran los campos y el tipo de campo de los documentos.
# sample fields and field types { "id":"number", "firstName":"string", "lastName":"string", "address":[ { "Street":"string", "City":"string", "State":"string" }, { "Street":"string", "City":"string", "State":"string" } ], "email":"string" }
También podemos insertar un solo registro usando la siguiente consulta:
PUT employee/_doc/4 { "id": 4, "firstName": "Paul", "lastName": "walker", "email": "paulwalker@org.com", "address": [ { "Street": "42 Oberoy street", "City": "Ohio", "State": "Nestville" } ] }
Producción:
3. Datos de inserción masiva:
La siguiente consulta realiza una operación de inserción masiva en el índice. Se insertarán los siguientes tres registros, después de insertar con éxito los datos, verifiquemos lo que tenemos hasta ahora.
Bulk Insert (use autoindent option to indent query) POST _bulk {"create":{"_index":"employee","_id":"1"}} {"id":1,"firstName":"Alice","lastName":"White","email":"alicewhite@org.com", "address":[{"Street":"2446 McDowell Street","City":"Palmyra","State":"Tennessee"},{"Street":"4809 Blackwell Street","City":"Dry Creek","State":"Alaska"}]} {"create":{"_index":"employee","_id":"2"}} {"id":2,"firstName":"Andrew","lastName":"Dunn","email":"andrewdunn@org.com", "address":[{"Street":"101 Ramsgate Rd","City":"Wildboarclough","State":"Alaska"}]} {"create":{"_index":"employee","_id":"3"}} {"id":3,"firstName":"Louis","lastName":"Hale","email":"louishale@org.com", "address":[{"Street":"84 Main St","City":"Archamore","State":"Las Vegas"}]}
Producción:
4. Obtener registros
La siguiente consulta se utiliza para obtener los datos del índice especificado ( empleado ). Obtendremos los registros que hemos insertado (3 registros):
GET employee/_search
Producción:
5. Agregue un nuevo campo en todos los registros.
Olvidamos agregar el campo de rol en los registros de empleados. ¿Ahora que? ¿Tenemos que eliminar todos los registros y agregar los registros con el campo de rol? No tenemos que hacer eso. Vamos a agregar solo un campo más en todos los registros.
Agreguemos un nuevo rol de campo con un valor emp . La siguiente consulta agregará un nuevo campo dentro de todos nuestros documentos:
POST /employee/_update_by_query/ { "script": "ctx._source.role = 'emp'" }
Producción:
Después de agregar un nuevo campo, obviamente, la estructura de nuestro documento cambiará. Esta será la estructura revisada después de agregar un nuevo campo.
{ "id":"number", "firstName":"string", "lastName":"string", "address":[ { "Street":"string", "City":"string", "State":"string" }, { "Street":"string", "City":"string", "State":"string" } ], "email":"string", "role":"string" }
6. Actualice el valor del campo según la condición.
Ahora bien, no es necesario que todos los empleados tengan el mismo rol. Algunos de ellos son administradores o gerentes, etc. Digamos que nos encontramos con un caso en el que queremos cambiar el rol de algunos empleados en función de alguna condición. La siguiente consulta cambiará el rol de los empleados que tienen el estado de Alaska en al menos una de las direcciones. Estamos recorriendo toda la array de direcciones del objeto empleado y verificando la condición si el estado es Alaska, si se evalúa como verdadero, estamos configurando el rol como administrador.
POST /employee/_update_by_query { "script": { "source": "for(a in ctx._source.address){if(a.State == 'Alaska'){ctx._source.role = 'admin'}}", "lang": "painless" } }
Producción:
7. Agregue un campo basado en la condición.
En la consulta No. 4, agregamos el campo de rol en todos los registros. Pero digamos que no queremos establecer el mismo valor de campo en todos los documentos. Ahora, para agregar los diferentes valores en algunos registros, habrá algunas condiciones sobre las cuales decidiremos qué establecer. Agreguemos un campo más isAdmin según el valor del rol. Si el rol es administrador , establezca isAdmin en verdadero o falso.
POST /employee/_update_by_query { "script": { "source": "if(ctx._source.role == 'admin'){ctx._source.isAdmin = true} else{ctx._source.isAdmin = false}", "lang": "painless" } }
Aquí estamos comprobando la condición simple if/else. La consulta anterior establecerá isAdmin en verdadero si el rol es administrador; de lo contrario, será falso.
Producción:
Después de agregar nuevamente un nuevo campo, el esquema también se cambia,
{ "id":"number", "firstName":"string", "lastName":"string", "address":[ { "Street":"string", "City":"string", "State":"string" }, { "Street":"string", "City":"string", "State":"string" } ], "email":"string", "role":"string", "isAdmin":"boolean" }
8. Cambiar el nombre de un campo
Los humanos a menudo cometemos algunos errores, errores tipográficos que a menudo conducen a que la producción disminuya. Pero lo más importante es que el sistema vuelva a funcionar con normalidad. Digamos que nos estamos refiriendo al estado en la array de direcciones en nuestro código, pero nuestros registros tienen Estado , lo que producirá errores. Ahora, queremos cambiar el nombre del campo de State -> state .
Cambiemos el nombre de un campo dentro de una array de direcciones. Estado a estado de dirección. A veces ocurre que insertamos datos con un error tipográfico en el nombre de los campos, usaremos la siguiente consulta para corregir el error tipográfico y cambiar el nombre de la clave:
POST /employee/_update_by_query { "script": { "source": "for(a in ctx._source.address){a.state = a.State; a.remove('State')}", "lang": "painless" } }
En la consulta anterior, estamos asignando el valor de State a state y luego eliminando el campo State de todos los elementos de la array de todos los registros.
Producción:
9. Eliminar un campo de todos los registros.
Los datos aumentan día a día, por lo que es un costo de almacenamiento. Nosotros, como desarrolladores, debemos almacenar solo lo que es necesario, la eliminación de campos innecesarios que a menudo crean discrepancias o irregularidades se vuelve esencial. Eliminemos el campo de rol de todos los registros:
POST /employee/_update_by_query { "script": { "source": "ctx._source.remove('role')", "lang": "painless" } }
La función de eliminación acepta el nombre del campo para eliminar. La consulta anterior elimina el campo de función de todos los registros.
Producción:
Después de eliminar el campo, nos quedamos con el siguiente esquema,
{ "id":"number", "firstName":"string", "lastName":"string", "address":[ { "Street":"string", "City":"string", "State":"string" }, { "Street":"string", "City":"string", "State":"string" } ], "email":"string", "isAdmin":"boolean" }
Las operaciones de agregar, actualizar, eliminar y obtener son el quid de cualquier sistema. Estas operaciones se utilizan en el día a día de un desarrollador.