Primeros pasos con elasticsearch
0.Índice de Contenidos
- 1. Introducción
- 2. Conceptos en los que se basa
- 3. Descarga e instalación
- 4. Jugando con elasticsearch
- 5. Extraer de Twitter una serie de Tweets
- 6. Usando el Api Java de elasticsearch
- 7. Buscando en la información indexada
- 8. Conclusiónes
1. Introducción
Elasticsearch es un producto que permite indexar y analizar en tiempo real grandes cantidades de datos de manera distribuida. Va un paso más allá de la búsqueda por texto gracias a un DSL y un Api para búsquedas más complicadas.
Elasticsearch permite almacenar documentos ( estructurados o no ) e indexar todos los campos de estos documentos en casi tiempo real.
Elasticsearch a diferencia de otros sistemas parecidos, no necesita declarar un esquema de la información que añadimos, pero para sacar mayor partido a la información tendremos que añadir los llamados mappings
que funcionan más o menos como un schema
.
Conceptos en los que se basa
Cluster
Un cluster es un conjunto de uno o más nodos que mantienen toda la información de manera distribuida e indexada. Cada cluster está identificado por un nombre, por defecto se llaman «elasticsearch».
Node
Un nodo es un server que forma parte de un cluster, almacena tu información y ayuda con las tareas de indexación y búsqueda del cluster. Los nodos están identificados por un nombre también, pero en este caso cada nodo está nombrado tras un personaje de Marvel.
Por defecto están configurados para ser parte de un cluster con el nombre de «elasticsearch».
Puede haber tantos nodos como quieras por cada Cluster, en caso de que no haya ningún Cluster configurado en el momento de creación este lo creará y se unirá a él.
Index
Un Index es una colección de documentos que tienen características similares. Los índices están identificados por un nombre, el cual usaremos a la hora de indexar, buscar, actualizar y borrar.
Sharding y Replicas
Cuando la información que estamos indexando sobrepasa el límite de una sola máquina, elasticsearch nos ofrece distintas maneras de saltarnos esa limitación.
El sharding nos permite dividir estos índices en distintas «piezas» ofreciéndonos la posibilidad de escalar horizontalmente (añadiendo más máquinas), además de paralelizar y distribuir las distintas operaciones que hagamos sobre esos índices.
La replicación nos ofrece un mecanismo para que en caso de fallo el usuario no se vea afectado.
Descarga e instalación
Para instalar necesitamos tener como mínimo la JDK 7 instalada en nuestro sistema.
Mediante la terminal, ejecutamos el siguiente comando para iniciar elasticsearch
$ cd to/download/folder
$ bin/elasticsearch
Esperamos a que termine de iniciarse y accedemos a la URL ( http://localhost:9200/ ) para ver que todo ha ido correctamente, nos debería aparecer una respuesta en formato JSON parecida a esta:
{ "status" : 200, "name" : "Captain Ultra", "version" : { "number" : "1.3.2", "build_hash" : "dee175dbe2f254f3f26992f5d7591939aaefd12f", "build_timestamp" : "2014-08-13T14:29:30Z", "build_snapshot" : false, "lucene_version" : "4.9" }, "tagline" : "You Know, for Search" }
Para ver el estado de nuestro nodo podriamos usar un plugin que nos permite ver en tiempo real el estado de elasticsearch.
El plugin se encuentra en la siguiente url, podemos seguir las instrucciones para instalar el plugin en local o acceder a través de esta url
Jugando con elasticsearch
Para ver elasticsearch en funcionamiento vamos a hacer una pequeña prueba de concepto, vamos a indexar los últimos tweets que hablen del mundial de baloncesto y vamos a buscar información dentro de esos Tweets.
Para ello vamos a usar la librería Twitter4J y el cliente Java de elasticsearch.
Extraer de Twitter una serie de Tweets
Para ello vamos a usar Twitter4J que nos proporciona un wrapper sobre la API de Twitter, podemos ver cómo configurar Twitter4J para hacer las peticiones a Twitter aquí, una vez lo tengamos configurado, nos disponemos a hacer una busqueda de texto, en este caso sobre el Mundial de Baloncesto:
public static List searchForTweets() throws TwitterException { Twitter twitter = new TwitterFactory().getInstance(); Query query = new Query("mundial baloncesto"); List tweetList = new ArrayList<>(); for (int i = 0; i < 10; i++) { QueryResult queryResult = twitter.search(query); tweetList.addAll(queryResult.getTweets()); if (!queryResult.hasNext()) { break; } query = queryResult.nextQuery(); } Gson gson = new Gson(); return tweetList.stream().map(gson::toJson).collect(Collectors.toList()); }
Con esto vamos a conseguir una lista de Tweets en un String en formato JSON, el siguiente paso sería crear un indice en el que almacenaremos los Tweets.
Usando el Api Java de elasticsearch
Elasticsearch nos ofrece diversas librerías cliente desde las cuales manejar los nodos/clusters/indices.
En nuestro caso vamos a crear un nuevo Índice para almacenar nuestros Tweets y vamos a añadirlos al indice.
Lo primero es indicarle a elasticsearch donde se encuentra instalado :
Client client = new TransportClient() .addTransportAddress(new InetSocketTransportAddress("localhost", 9300));
Aunque a por HTTP nos conectemos a través del puerto 9200, el cliente se conecta a través del puerto 9300.
El siguiente paso es crear un index, en el que almacenaremos los Tweets.
String index = "tweets"; client.admin().indices() .create(new CreateIndexRequest(index)) .actionGet();
Con este código habremos creado un index con el nombre tweets, el siguiente paso es añadir los tweets a este index para poder buscar en ellos.
public static void indexExampleData(Client client, List tweetJsonList, String index) { BulkRequestBuilder bulkRequestBuilder = client.prepareBulk(); tweetJsonList.forEach((jsonTweet) -> { bulkRequestBuilder.add(new IndexRequest(index, "tweet") .source(jsonTweet)); }); BulkResponse bulkItemResponses = bulkRequestBuilder.get(); }
Para esto vamos a usar una Request de tipo bulk
el cual se usa para realizar distintas acciones en una misma petición, en este caso todas las acciones serán de tipo add index
, pero podría haber acciones de distintos tipos en la misma bulk request
.
Buscando en la información indexada
Elasticsearch ofrece muchas posibilidades de búsqueda, dependiendo de las necesidades que tengas se adapta a ellas. En este caso vamos a hacer una búsqueda sencilla por texto, buscando solo en el texto del tweet.
SearchResponse searchResponse = client.prepareSearch("tweets") .setQuery(QueryBuilders.termsQuery("text", "españa")) .setSize(25) .execute() .actionGet();
Buscamos en el index tweets
aquellos tweets que contengan el texto "españa", "text" es el campo que contiene el texto del tweet, si quisiéramos buscar en otros campos como podría ser el nombre del usuario que ha posteado el tweet.
En este caso vemos que aparece demasiadas veces la palabra "apuesta", si quisiéramos realizar una query que ignorase todos aquellos resultados que contuvieran la palabra "apuesta" podríamos hacerlo de la siguiente manera:
import static org.elasticsearch.index.query.QueryBuilders.termsQuery; public static void searchExample(Client client) { BoolQueryBuilder queryBuilder = QueryBuilders .boolQuery() .must(termsQuery("text", "españa")) .mustNot(fuzzyQuery("text", "apuesta")); SearchResponse searchResponse = client.prepareSearch("tweets") .setQuery(queryBuilder) .setSize(25) .execute() .actionGet(); }
En este caso hemos elegido la búsqueda "fuzzy" que usando algoritmos de comparación de cadenas de texto, busca términos similares al introducido, por ejemplo
Conclusiones
Elasticsearch nos ofrece la posibilidad de hacer búsquedas de texto tan complicadas como sean nuestras necesidades, visualizar el estado de nuestros nodos, y escalar sin demasiadas necesidades si se diera el caso de que necesitáramos más potencia.
Muchas gracias por tu ayuda. Esto me dio una idea de lo que es Elasticsearch.
disculpa amigo para borrar un index y crearlo de nuevo?
Daniel muchas gracias por el tutorial. Tengo una inquietud, cuál sería la diferencia entre elasticsearch y hadoop?
[…] 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 […]
[…] http://adictosaltrabajo.com/tutoriales/primeros-pasos-elasticsearch/ […]
Gracias por el vistazo, empiezo en dos días con un curro de esto 🙂
P.t.i.:
«El Api de Java nos permite realizar busquedas más complicadas, podemos ver un resumen del DSL que nos ofrece la query aquí.»
El «aquí» a perdido el enlace…
«En este caso hemos elegido la búsqueda “fuzzy” que usando algoritmos de comparación de cadenas de texto, busca términos similares al introducido, por ejemplo »
Y no hay ningún ejemplo…
Saludos!
En el párrafo que dice:
«Con este código habremos creado un index con el nombre tweets, el siguiente paso es añadir los tweets a este index para poder buscar en ellos», en la línea 7, el comado no debiera usar la palabra «tweets» en vez de «tweet»?
Si lo entendí bien, lo que hace es añadir al index «tweets» un elemento «tweet» que es cada elemento de la lista, como identificador del elemento que está guardando en el index «tweets», todos tienen el mismo identificador. Entiendo que como después la forma de recuperar esa información es a través de palabras clave (incluidas o excluidas), pues no tendría sentido meterle un identificador unívoco.
Saludos.
Genial el artículo. Una maravilla.
Tienes el código subido a algún git?