ElasticSearch: Demo

Debido a recientes cambios en el ámbito laboral, recientemente he empezado a trabajar con ElasticSearch y me ha tocado, cosa genial no os equivoquéis, estudiar un poco esta tecnología, como funciona y, antes de empezar con el proyecto real, realizar unas pequeñas demos. Una de las primeras, es la que os traigo aquí. Es bastante simple, pero para explicar los primeros pasos es bastante aceptable.

Para empezar, ¿qué es ElasticSearch? Básicamente nos ofrece una instancia de un servidor para la indexación y búsqueda de contenido añadido a la instancia. Además, nos ofrece un API REST para poder acceder a la información.

El primer paso, sería instalar una instancia en nuestra máquina local. Nada más fácil, solo hay que descargar un pequeño .zip y descomprimirlo. Tenéis el ejecutable y las instrucciones en la página aquí.

Como siguiente paso, es bastante interesante, en entornos de desarrollo, ya que sino requiere el pago de una licencia, es instalar Marvel, que además de muchos paneles con información varia, tiene un panel muy interesante llamado “Sense” en el que podemos escribir nuestras consultas y consumir directamente el API REST de ElasticSearch y además, nos ofrece cierto grado de auto completado.

Para instalarlo, nada más fácil, nos dirigimos al directorio de instalación de ElasticSearch y ejecutamos:

bin/plugin -i elasticsearch/marvel/latest

Tras esto, podremos acceder a los paneles con la URL:

http://any-server-in-cluster:9200/_plugin/marvel/

Aquí podemos seleccionar el panel de Sense y jugar un rato con las queries que nos ofrece la documentación y el API REST que nos ofrece ElasticSearch. Pero bueno, el objetivo de este post es usar Java para ejecutar operaciones sobre la instancia de ElasticSearch.

El projecto lo tenéis en la URL habitual del repositorio aquí.

El projecto consta de unos pocos ficheros, ya que lo he hecho lo más básico posible y intentando añadir solo el código necesario para para ejecutar las operaciones de añadir (index), actualizar (update), borrar (delete) y ejecutar las búsquedas.

El fichero pom.xml contiene unas pocas dependencias básicas, todas ellas fácilmente identificables:

<!-- ElasticSearch -->
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>1.1.0</version>
</dependency>

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.18.1</version>
</dependency>

<!-- Apache Common BeanUtils -->
<dependency></span></div>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.2</version>
</dependency>

Tras echarle una ojeada a esto que yo creo que no necesita ninguna explicación, la otra clase interesante es la de ElasticSearch.

public static final String INDEX_NAME = "myindex"; // Must be lowercase
public static final String TYPE_NAME = "article";
public static final String SERVER = "localhost";
public static final int PORT= 9300;

Las variable que utilizaremos para hacer las conexiones a la instancia de ElasticSearch. Tenemos el nombre del índice y el tipo de objeto que vamos a insertar. Además, de ellos tenemos los datos de conexión al la instancia.

Por da una introducción breve y equiparar este sistema al que todos conocemos de BBDD relacionales, el equivalente, sería algo así:

Relacionales: Esquema – Tabla – Columna – Campo

ElasticSearch: Índice – Tipo – Objecto – Campo

De esta forma yo creo que es fácil de entender. Si luego necesitáis crear clusters o distribuir vuestros índice en varias instancias ya tendréis que tomar decisiones entre que es mejor, si un objeto por índice, o un índice con muchos tipos dentro, o…

Volviendo a la clase Java, si nos fijamos básicamente, todos los métodos en ella tiene la misma estructura: La conexión con el objeto “Client”, y la operación que queremos realizar pasándole los datos que necesitamos.

Client client = new TransportClient().addTransportAddress(new InetSocketTransportAddress(ElasticSearch.SERVER, ElasticSearch.PORT));

El único método que destaca un poco, es el método update que en vez de realizar una operación de actualización como tal, ejecuta un borrado y una nueva inserción, esto es así porque la velocidad de trabajo de ElasticSearch lo permite y además, el API no ofrece la posibilidad de actualización. Bueno, realmente, sí que se puede hacer a través de una ejecución de scripts, pero no merece la pena, al menos, en un caso tan general como este.

// Update the element in ElasticSearch
public static void updateArticle(Article article) throws Exception {
    ElasticSearch.deleteArticle(article.getId());

    ElasticSearch.indexArticle(article);
}

En el caso de la búsqueda, en el ejemplo, se ha utilizado una de las “queries” más generales que hay, y sobre esto sí que tenéis que echarle un ojo más a fondo porque hay muchísimas de ellas, con múltiples opciones. Pero para este ejemplo, era más que suficiente con esta búsqueda básica.

QueryBuilder queryBuilder = QueryBuilders.matchQuery("_all", searchTerm);

Echadle un ojo al código, y si tenéis alguna duda ya sabéis. Nos vemos.

ElasticSearch: Demo