Jugando con Elasticsearch y Java

En el curro estamos empezando a usar Elasticsearch para algunos temas. Como a mí en concreto no me ha tocado, me ha dado por hacer algunas pruebas por mi cuenta, desde Java, y así aprender lo básico.

Llevo un par de días con ellos … y no sé si me convence. No Elasticsearch en sí, no he hecho pruebas de rendimiento, ni con clusters ni nada de nada. Sólo con la API de Java.

¿Y por qué no me convence?. Varios motivos.

Fluent builders de la API Java de Elasticsearch

La web de Elasticsearch, respecto a la nueva API de Java, pone

Use of fluent builders and functional patterns to allow writing concise yet readable code when creating complex nested structures.

básicamente, que como se usan «fluent builders», las estructuras complejas anidadas se hacen más concisas y legibles. Aquí un ejemplo de código de la documentación.

// Search by product name
Query byName = MatchQuery.of(m -> m 
    .field("name")
    .query(searchText)
)._toQuery(); 

// Search by max price
Query byMaxPrice = RangeQuery.of(r -> r
    .field("price")
    .gte(JsonData.of(maxPrice)) 
)._toQuery();

// Combine name and price queries to search the product index
SearchResponse<Product> response = esClient.search(s -> s
    .index("products")
    .query(q -> q
        .bool(b -> b 
            .must(byName) 
            .must(byMaxPrice)
        )
    ),
    Product.class
);

Pues como promete la documentación, es una sintaxis «sencilla» y sobre todo «legible» para consultar productos con un nombre concreto y un precio máximo. No quiero ni imaginarme cómo será una consulta con más condiciones.

Documentación escasa

La documentación oficial es muy escueta, poco o nada didáctica. Las búsquedas por google tampoco dan mucha más información más allá de la documentación oficial. Quizás porque esta API de Java es relativamente nueva en Elasticsearh, antes se usaba directamente una API REST.

Si te fijas en el ejemplo anterior, para buscar por nombre usa MatchQuery y para lo del precio máximo RanqeQuery. Más allá del Javadoc, no he encontrado un tutorial «didáctico» donde te explique las alternativas que hay, cómo se usan, etc.

En fin, toda una odisea de búsqueda de documentación, prueba, ensayo y error como quieras hacer algo más allá de una consulta simple.

Aunque no sea exactamente de la API de Java, reto a alguien a que me diga que roles son los que hay que poner al crear un usuario que quieras que haga las típicas operaciones CRUD. Aquí tienes la lista de roles predefinidos.

Dichosa caché

En mis pruebas, un main sencillo, todo seguido: crear un índice, insertar, hacer un search para consultar lo insertado …. y la consulta no devuelve nada. Mirando directamente con el navegador web conectado a la URL de Elasticsearch veo que los datos sí se han insertado.

Un buen rato probando la consulta, por id de objeto insertado con get() funciona, con search() y condiciones no funcina, pongas lo que pongas…. pero de forma aleatoria, alguna vez sí va.

Así que sospechando de algo similar al commit que se hace con las tradicionales SQL, veo que hay un elasticsearchClient.indices().flush(). Tampoco va. Pero si después de eso pones un sleep() entonces ya funciona todo.

Es decir, tiene pinta de que en el mismo programa, con la misma instancia de elasticearchClient hay alguna caché que es distinta para cada operación y lo que insertas en una línea, no está disponbile para consulta en la siguiente.

Hay dos clases cliente de Elasticsearch. Una es síncrona y la otra asíncrona. La síncrona teóricamente te devuelve el control una vez ha terminado la operación, la asíncrona te lo devuelve inmediatamente aunque no haya terminado la operación.

¿Con cual de las dos crees que me estaba pasando lo de insertar y no tener disponibles los resultados?

¡¡Efectivamente, lo has adivinado!!. ¡¡Con la SINCRONA!!.

Una lanza a favor de Elasticsearch

En el curro, como comento, lo están usando. Pero lo usan en combinación con Kibana, o con clusters de nodos por el tema de alta disponibilidad, etc. Parece que en ese sentido la gente está muy contenta.

El uso que están dando es el almacenamiento masivo de información procedente de sensores desde uno o varios ejecutables separados. Luego con Kibana o bien con una aplicación hecha a medida, las consultas de esos datos históricos. Con Kibana no hay que pelearse con las consultas. Con la aplicación a medida seguramente topes con el primer problema que he comentado, pero todo es cuestión de pelearse y acostumbrarse.

En cuanto a cluster de nodos, parece que dos grupos de trabajo que lo han probado por separado e implementado en sus proyectos han quedado contentos con su comportamiento.

Conclusión

Pues lo dicho, no parece adecuada para uso como una base de datos de trabajo normal. Pero sí parece adecuada para meter muchos datos en cluster y análisis a posteriori de dichos datos, bien con Kibana, bien con aplicaciones a medida.

Esta entrada ha sido publicada en elasticsearch y etiquetada como , . Guarda el enlace permanente.

Una respuesta en “Jugando con Elasticsearch y Java

  1. Pingback: Java switch e instanceof Pattern Matching | Diario de Programación

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.