Blog de Gonzalo

ELASTICSEARCH

Hace poco me enteré de la existencia de elasticsearch y he estado indagando un poco para saber lo que era. Elasticsearch se puede definir como un producto para indexar y analizar en tiempo real grandes cantidades de datos de manera distribuida.
Elasticsearch diferencia de otros sistemas parecidos, como sphinx 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.
Elasticsearch se basa en Lucene (una API de código abierto para recuperación de información, originalmente implementada en Java. Está apoyado por el Apache Software) pero expone su funcionalidad a través de una interfaz REST recibiendo y enviando datos en formato JSON y oculta mediante esta interfaz los detalles internos de lucene. Esta interfaz permite que pueda ser utilizada por cualquier plataforma no solo Java, puede usarse desde Python, .NET, PHP o incluso desde un navegador con Javascript. Es persistente, es decir, que lo que indexemos en ella sobrevivirá a un reinicio del servidor.
Conceptos:

  • Cluster:Un cluster es un conjunto de uno o más nodos que mantienen toda la información de manera distribuida e indexada.
  • Nodo: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 nodostambién se identifican por nombre. Puede haber varios nodos por cluster.
  • Index:Un index es una colección de documentos que tienen características similares. Los índices están identificados por un nombre, el cual será usado cuando se indexe, busque, actualice y borre.
  • Sharding y Replicas:Cuando la información se está indexando sobrepasa el límite de una sola máquina, elasticsearch ofrece distintas maneras de evitar esa limitación. El sharding permite dividir los índices en diferentes "partes" ofreciendo 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 y la replicación ofrece un mecanismo para que en caso de fallo el usuario no se vea afectado.

Ahora veamos un pequeño ejemplo en php usando mysql. Creo que sería un buen ejemplo práctico y real:

require 'vendor/autoload.php';
class SearchElastic
{
private $elasticclient = null;
public function __construct()
{
$this->elasticclient = Elasticsearch\ClientBuilder::create()->build();
}

En el código anterior se carga el API de elasticsearch y se crea una variable para manejar la la conexión de elasticsearch dentro de la clase.

 public function Mapping(){
$params = [
'index' => 'articulos',
'body' => [
'mappings' => [
'articulo' => [ 'propiedades' => [
'id' => [
'type' => 'integer'
],
'nombre' => [
'type' => 'string'
],
'descipcion' => [
'type' => 'string'
], 'url' => [
'type' => 'string'
],
'categoria' => [
'type' => 'string'
],
'image' => [
'type' => 'string'
],
]
]
]
]
];
$this->elasticclient->indices()->create($params);

El código anterior crea el mapeo de los tipos de datos que se van a almacenar en elasticsearch.

	while ($row = $result->fetch_assoc())
{
$params['body'][] = array(
'index' => array(
'_index' => 'articulos',
'_type' => 'articulo',
'_id' => $row['article_id'],
) ,
);
$params['body'][] = ['nombre' => $row['article_name'],
'desccripcion' => $row['article_content'], 'url' => $row['url'],
'categoria' => $row['category_name'], 'image' => $row['img'], ];
}
$this->Mapping();
$responses = $client->bulk($params);

En la función anterior se guarda la información recibida de la base de datos. He obviado el tema de la conexión y ejecución de la query. La función bulk se usa para guardar una gran cantidad de datos.

   public function DeleteNode($id)
{
$client = $this->elasticclient;
$params = ['index' => 'articulos', 'type' => 'articulo', 'id' => $id, ];
$responses = $client->delete($params);
return true;
}

El código anterior es sencillito. Sirve para borrar un nodo y no interesa que salga en lso resultados de búsqueda.


public function Search($query)
{
$client = $this->elasticclient;
$result = array();
$i = 0;
$params = ['index' => 'articulos', 'type' => 'articulo', 'body' =>
['query' => ['match' => ['descripcion' => $query], ], ], ];
$query = $client->search($params);
$hits = count($query['hits']['hits']);
$hit = $query['hits']['hits'];
$result['searchfound'] = $hits;
while ($i < $hits) {
$result['result'][$i] = $query['hits']['hits'][$i]['_source'];
$i++;
}
return $result;
}

Y ya por último el código anterior muestra como realizar una búsqueda en elasticsearch evitando tener que usar la base de datos y así se ahorran recursos y tiempo.
Este ejemplo es bastante completo y creo que bastante útil. Espero que os haya parecido sencillo.

Compartir en twitter