Si necesitas hacer una búsqueda de texto completo, pro­ba­ble­me­n­te elijas Apache Solr y, en efecto, será una buena elección, pero desde 2010 el mercado ofrece una al­te­r­na­ti­va in­te­re­sa­n­te: Ela­s­ti­c­sea­r­ch. Al igual que Solr, Ela­s­ti­c­sea­r­ch está basado en Apache Lucene, pero cuenta con otras funciones muy in­te­re­sa­n­tes. Te ex­pli­ca­mos las ca­ra­c­te­rí­s­ti­cas del servidor de búsqueda y cómo im­ple­me­n­tar la búsqueda de texto completo para tu proyecto con nuestro tutorial de Ela­s­ti­c­sea­r­ch.

Ela­s­ti­c­sea­r­ch es uno de los bu­s­ca­do­res de texto completo más im­po­r­ta­n­tes de Internet. Grandes empresas como, por ejemplo, Facebook, GitHub, Netflix, Sou­n­d­Cloud o Zalando llevan años tra­ba­ja­n­do con el software con mucho éxito.

¿Qué es Ela­s­ti­c­sea­r­ch?

Dada la gran cantidad de in­fo­r­ma­ción con la que cuentan algunos sitios web, solo se puede ga­ra­n­ti­zar un alto nivel de fu­n­cio­na­li­dad im­ple­me­n­ta­n­do una búsqueda de texto completo. Si no quieres recurrir a las he­rra­mie­n­tas de Google o Bing para ofrecer a tus vi­si­ta­n­tes una función de búsqueda, tendrás que insertar la tuya propia. Esto es posible, por ejemplo, con Ela­s­ti­c­sea­r­ch. Este software libre se basa en la versión gratuita de Apache Lucene.

Ela­s­ti­c­sea­r­ch ofrece las ventajas de sus pre­de­ce­so­res e incluye otras ca­ra­c­te­rí­s­ti­cas. Como en el caso de Lucene, la búsqueda se realiza mediante un índice, pero en lugar de examinar todos los do­cu­me­n­tos, el programa comprueba un índice de do­cu­me­n­tos que se ha creado pre­via­me­n­te en el que todo el contenido se almacena de forma preparada. Este proceso requiere mucho menos tiempo que la consulta de todos los do­cu­me­n­tos.

Aunque Lucene ofrece total libertad en cuanto a dónde y cómo utilizar la búsqueda de texto completo, con este software se parte de cero. A cambio, Ela­s­ti­c­sea­r­ch facilita los primeros pasos en la Web. Con Ela­s­ti­c­sea­r­ch es posible construir un servidor de búsqueda estable en poco tiempo que también se puede di­s­tri­buir fá­ci­l­me­n­te entre varios equipos.

Uti­li­za­n­do el llamado sharding, varios nodos (di­fe­re­n­tes se­r­vi­do­res) se unen para formar un clúster: Ela­s­ti­c­sea­r­ch desglosa el índice y di­s­tri­bu­ye las partes in­di­vi­dua­les (shards) entre varios nodos, di­vi­die­n­do así la carga de cálculo. Para proyectos grandes, la búsqueda de texto completo es mucho más estable y, en caso de que busques mayor seguridad, también puedes copiar los fra­g­me­n­tos a varios nodos.

Ela­ti­c­sea­r­ch se basa, al igual que Lucene, en el lenguaje de pro­gra­ma­ción orientado a objetos Java. El motor de búsqueda produce los re­su­l­ta­dos en formato JSON y los entrega a través de un servicio web REST. La API facilita la in­te­gra­ción de la función de búsqueda en un sitio web.

Además, Ela­s­ti­c­sea­r­ch ofrece con Kibana, Beats y Logstash (conocidos juntos como Elastic-Stack) servicios adi­cio­na­les que se pueden utilizar para analizar la búsqueda de texto completo. La empresa Elastic, que está detrás del de­sa­rro­llo de Ela­s­ti­c­sea­r­ch y que fue fundada por el inventor del programa, también ofrece servicios de pago, como el cloud hosting.

¿Qué ofrece Ela­s­ti­c­sea­r­ch que no tengan los grandes motores de búsqueda?

Si Google te permite integrar su popular función de búsqueda en tu página web sin ningún problema, ¿por qué motivo deberías decidirte por una opción más tediosa que te exige de­sa­rro­llar tu propio motor de búsqueda con Ela­s­ti­c­sea­r­ch? Con la Búsqueda Pe­r­so­na­li­za­da de Google (GCS) dependes del gigante de los motores de búsqueda y has de re­si­g­nar­te, al menos en la versión gratuita, a la pu­bli­ci­dad en los re­su­l­ta­dos. Esto puedes evitarlo con Ela­s­ti­c­sea­r­ch, porque el código es open source, lo que significa que, una vez has im­ple­me­n­ta­do la función de búsqueda de texto completo, ya no le pertenece a nadie más que a ti.

Además, Ela­s­ti­c­sea­r­ch puede pe­r­so­na­li­zar­se por completo. Si, por ejemplo, operas tu propia pla­ta­fo­r­ma o una tienda online, puedes co­n­fi­gu­rar la función de búsqueda para que también puedan ex­plo­rar­se los perfiles re­gi­s­tra­dos. GCS, no obstante, llega al límite de sus ca­pa­ci­da­des en estos ámbitos de apli­ca­ción.

Ela­s­ti­c­sea­r­ch vs. Apache Solr: ¿cuáles son las pri­n­ci­pa­les di­fe­re­n­cias?

Tanto Ela­s­ti­c­sea­r­ch como Apache Solr están basados en Lucene, pero han sido de­sa­rro­lla­dos para pro­po­r­cio­nar ofertas in­de­pe­n­die­n­tes. Muchos usuarios se preguntan qué proyecto les vendría mejor. Aunque Ela­s­ti­c­sea­r­ch es un poco más joven y no cuenta con el respaldo de la ex­pe­ri­me­n­ta­da comunidad de Apache, ha superado a Solr en número de usuarios. El principal motivo es que su im­ple­me­n­ta­ción es mucho más sencilla. Además, Ela­s­ti­c­sea­r­ch es popular por su manejo de datos dinámicos: gracias a un pro­ce­di­mie­n­to especial de al­ma­ce­na­mie­n­to en caché, Ela­s­ti­c­sea­r­ch hace posible que los cambios no tengan que ser in­tro­du­ci­dos en la caché global. En su lugar, es su­fi­cie­n­te con cambiar un pequeño segmento, lo que hace a Ela­s­ti­c­sea­r­ch mucho más flexible.

Sin embargo, con fre­cue­n­cia la elección de uno u otro software dependerá del enfoque que se dé al de­sa­rro­llo del código abierto. Solr está to­ta­l­me­n­te co­m­pro­me­ti­do con la Apache Software Fou­n­da­tion: community over code. Esto supone que cada co­n­tri­bu­ción al código se valora se­ria­me­n­te y la comunidad en conjunto decide qué co­m­ple­me­n­tos y mejoras se incluirán en el código final. El de­sa­rro­llo de Ela­s­ti­c­sea­r­ch es diferente. Si bien también es un proyecto de código abierto que se ofrece bajo una licencia libre de Apache, en este caso solo el equipo de Elastic decide qué cambios se hacen en el código. Contra esta me­n­ta­li­dad ga­te­kee­per algunos de­sa­rro­lla­do­res se revelan y, en co­n­se­cue­n­cia, optan por Solr.

Tutorial de Ela­s­ti­c­sea­r­ch

Si empiezas a trabajar con Ela­s­ti­c­sea­r­ch, lo primero que debes hacer es conocer algunos términos básicos. Empecemos por mencionar la es­tru­c­tu­ra de la in­fo­r­ma­ción en el programa:

  • Index: una búsqueda en Ela­s­ti­c­sea­r­ch nunca arroja el contenido como respuesta, sino el índice, en el cual se almacenan, ya pre­pa­ra­dos, todos los co­n­te­ni­dos de todos los do­cu­me­n­tos. De esta forma la búsqueda requiere muy poco tiempo. Es el llamado inverted index (índice invertido): para cada término de búsqueda se indica el lugar donde se puede encontrar dicho término.
  • Document: la salida para el índice son los do­cu­me­n­tos, en los cuales aparecen los datos. No tienen que ser ne­ce­sa­ria­me­n­te textos completos (por ejemplo, artículos de blogs) –es su­fi­cie­n­te que se trate de archivos con in­fo­r­ma­ción.
  • Field: un documento, a su vez, consta de varios campos. Además del campo de contenido pro­pia­me­n­te dicho, hay otros metadatos que también forman parte de un documento. Por ejemplo, Ela­s­ti­c­sea­r­ch puede uti­li­zar­se para buscar metadatos sobre el autor o el momento de la creación.

Por cierto, cuando hablamos de la pre­pa­ra­ción de datos, estamos haciendo re­fe­re­n­cia a co­n­ve­r­ti­r­los en tokens, acción conocida por su nombre en inglés to­ke­ni­zi­ng. En este proceso, un algoritmo crea términos in­di­vi­dua­les a partir de un texto completo. Para el ordenador no existen las palabras, sino que para él un texto consiste en una larga cadena de ca­ra­c­te­res y una letra tiene el mismo valor que un espacio. Para que un texto sea fo­r­ma­tea­do con sentido, primero debe ser dividido en tokens. Para ello se toma el espacio en blanco (whi­te­s­pa­ce, es decir, espacios y líneas en blanco) como marcador para palabras. Durante la pre­pa­ra­ción, también se normaliza: todas las palabras se escriben en mi­nú­s­cu­las y los signos de pu­n­tua­ción se ignoran. Ela­s­ti­c­sea­r­ch ha adoptado todos estos métodos de Apache Lucene.

Nota

En el siguiente tutorial de Ela­s­ti­c­sea­r­ch tra­ba­ja­mos con la versión 6.3.0. Si estás usando una versión diferente, puede que algunos ejemplos de código o los pasos del tutorial deban llevarse a cabo de forma diferente

In­s­ta­la­ción

Los archivos ne­ce­sa­rios para Ela­s­ti­c­sea­r­ch están di­s­po­ni­bles gra­tui­ta­me­n­te en el sitio web oficial de Elastic como paquetes ZIP o tar.gz, por lo que son fáciles de instalar en Linux y Mac a través de una consola.

Nota

Elastic ofrece Ela­s­ti­c­sea­r­ch en dos paquetes di­fe­re­n­tes. La versión estándar incluye funciones de pago que puedes usar durante un tiempo de­te­r­mi­na­do gracias a una versión de prueba. Estos paquetes, que están marcados con OSS (Open Source Software), solo contienen co­m­po­ne­n­tes libres que han sido pu­bli­ca­dos bajo la licencia Apache 2.0.

Para ZIP:

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.zip
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.zip.sha512
shasum -a 512 -c elasticsearch-oss-6.3.0.zip.sha512 
unzip elasticsearch-oss-6.3.0.zip
cd elasticsearch-6.3.0

Para tar.gz:

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.tar.gz
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.tar.gz.sha512
shasum -a 512 -c elasticsearch-oss-6.3.0.tar.gz.sha512 
tar -xzf elasticsearch-oss-6.3.0.tar.gz
cd elasticsearch-6.3.0

En primer lugar, descarga el paquete y luego la suma de ve­ri­fi­ca­ción hash (SHA512), que podrás comprobar en el tercer paso. A co­n­ti­nua­ción, de­s­co­m­pri­me el paquete y cámbialo a la carpeta co­rre­s­po­n­die­n­te.

El archivo ZIP se puede descargar también para uti­li­zar­lo con Windows, ya que el paquete contiene un archivo batch que puedes ejecutar. Ahora, Elastic pro­po­r­cio­na también un in­s­ta­la­dor MSI, aunque aún se encuentra en fase beta. Este pro­po­r­cio­na un archivo de in­s­ta­la­ción cuya interfaz gráfica te guiará durante todo el proceso.  

Nota

Dado que Ela­s­ti­c­sea­r­ch está basado en Java, tu sistema debe tener instalado este lenguaje de pro­gra­ma­ción. Lo mejor es descargar gratis el Java De­ve­lo­p­me­nt Kit (JDK) desde la página web oficial.

A co­n­ti­nua­ción, ejecuta Ela­s­ti­c­sea­r­ch desde la consola, dirígete a la carpeta bin e introduce “ela­s­ti­c­sea­r­ch”, ya sea en Linux, Mac o Windows. A co­n­ti­nua­ción, abre un navegador y accede al siguiente puerto del host local: 'http://localhost:9200/'. Si has instalado Ela­s­ti­c­sea­r­ch co­rre­c­ta­me­n­te y Java también está bien co­n­fi­gu­ra­do, deberías poder acceder a la búsqueda de texto completo.

Con Ela­s­ti­c­sea­r­ch te comunicas a través de la API REST, por lo que necesitas un cliente adicional. Se re­co­mie­n­da usar Kibana (que es otro software de código abierto de Elastic). Con este programa puedes utilizar Ela­s­ti­c­sea­r­ch di­re­c­ta­me­n­te en tu navegador. Para ello, basta con ir a "http://localhost:5601/" y acceder a una interfaz gráfica de usuario. Cómo instalar y co­n­fi­gu­rar Kibana co­rre­c­ta­me­n­te se explica en nuestro tutorial para Kibana. En Kibana y en cualquier otro cliente puedes utilizar los métodos HTTP PUT, GET, POST y DELETE para enviar comandos a tu búsqueda de texto completo.

Indexar

El siguiente paso consiste en crear un índice e in­tro­du­cir los datos. Para ello, puedes utilizar dos métodos HTTP di­fe­re­n­tes: POST y PUT. Utiliza PUT si deseas es­pe­ci­fi­car un ID de­te­r­mi­na­do para la entrada. En POST, Ela­s­ti­c­sea­r­ch crea su ID propio. En nuestro ejemplo queremos hacer una bi­blio­gra­fía, de forma que cada entrada debe contener el nombre del autor, el título de la obra y el año de pu­bli­ca­ción.

POST bibliography/novels
{
"author": "Isabel Allende",
"title": "La casa de los espíritus",
"year": "1982"
}

Si deseas utilizar la entrada de esta manera, tienes que usar la consola de Kibana. Sin embargo, si no quieres usar este software, tienes la opción de recurrir a cURL. En lugar del comando anterior, debes in­tro­du­cir lo siguiente en la línea de comandos:

curl -XPOST http://localhost:9200/bibliography/novels -H "Content-Type: application/json" -d '{"author": "Isabel Allende", "title": "La casa de los espíritus", "year": "1982"}'

A co­n­ti­nua­ción, te mostramos solo el código para Kibana, pero puedes adaptarlo fá­ci­l­me­n­te a la sintaxis de cURL.

Si has in­tro­du­ci­do todo co­rre­c­ta­me­n­te, Ela­s­ti­c­sea­r­ch debería ofrecer la siguiente in­fo­r­ma­ción al principio del mensaje:

{
	"_index": "bibliography",
	"_type": "novels",
	"_id": "AKKKIWQBZat9Vd0ET6N1",
	"_version": 1,
	"result": "created",
}

Como se ve aquí, Ela­s­ti­c­sea­r­ch encuentra un índice con el nombre bi­blio­gra­fía y el tipo novela. Como hemos usado el método POST, Ela­s­ti­c­sea­r­ch generó au­to­má­ti­ca­me­n­te un ID único para nuestra entrada. La entrada se encuentra ahora en la primera versión y se ha creado re­cie­n­te­me­n­te (created).

Nota

Un tipo (_type) solía ser una especie de su­b­ca­te­go­ría en Ela­s­ti­c­sea­r­ch. A través de esta su­b­ca­te­go­ría, era posible reunir varios tipos bajo un mismo índice. No obstante, debido a los problemas de diversa índole a los que esto condujo, Elastic está planeando dejar de utilizar estos tipos. En la versión 6.x, _type sigue estando incluido, pero ya no es posible reunir varios tipos bajo un mismo índice. A partir de la versión 7.0 está previsto eliminar todos los tipos, como explican los de­sa­rro­lla­do­res en su blog.

También puedes utilizar PUT para dar a tu entrada un ID es­pe­cí­fi­co que debes definir en la primera línea del código. También necesitas PUT si deseas modificar una entrada existente.

PUT bibliography/novels/1
{
"author": "William Gibson",
"title": "Neuromancer",
"year": "1984"
}

La siguiente salida es muy similar a la que obtenemos con el método POST, pero, en este caso, Ela­s­ti­c­sea­r­ch nos da el ID que le dimos a la entrada en la primera línea. El orden de la in­fo­r­ma­ción es siempre _index/_type/_id.

{
	"_index": "bibliography",
	"_type": "novels",
	"_id": "1",
	"_version": 1,
	"result": "created",
}

Con el comando PUT y el ID único también podemos cambiar las entradas:

PUT bibliography/novels/1
{
"author": "William Gibson",
"title": "Count Zero",
"year": "1986"
}

Como la entrada con el ID 1 ya existe, Ela­s­ti­c­sea­r­ch solo la modifica, en lugar de crear una nueva. Esto también se refleja en el resultado:

{
	"_index": "bibliography",
	"_type": "novels",
	"_id": "1",
	"_version": 2,
	"result": "updated",
}

El número de la versión es ahora el 2 y como result se obtiene un updated, en lugar de un created. Puedes hacer lo mismo con un ID aleatorio creado por Ela­s­ti­c­sea­r­ch pero, debido a la longitud y al desorden de los ca­ra­c­te­res, el trabajo posterior sería mucho más engorroso. En co­n­se­cue­n­cia, si te equivocas al in­tro­du­cir los números de ide­n­ti­fi­ca­ción puede ocurrir que Ela­s­ti­c­sea­r­ch so­bre­s­cri­ba una entrada. Para evitar so­bre­s­cri­tu­ras ac­ci­de­n­ta­les, puedes emplear _create al final de la línea:

PUT bibliography/novels/1/_create
{
"author": "Mary Shelley",
"title": "Frankenstein; or, The Modern Prometheus",
"year": "1818"
}

Al existir ya una entrada con el ID 1 en el índice, aparece un mensaje de error.

Si se realizan mo­di­fi­ca­cio­nes en una entrada tal y como se ha descrito hasta ahora, se crea una entrada to­ta­l­me­n­te nueva y, por lo tanto, se deben in­tro­du­cir todos los datos por completo. No obstante, también puedes integrar mo­di­fi­ca­cio­nes en la entrada existente, uti­li­za­n­do para ello el parámetro _update:

POST bibliography/novels/1/_update
{
"doc": {
	"author": "Franz Kafka",
"genre": "Horror"
	}
}

Lo que hemos hecho aquí arriba es añadir un campo adicional a la entrada y hemos cambiado un campo existente sin borrar los otros, pero solo en primer plano. En un segundo plano Ela­s­ti­c­sea­r­ch ha creado una entrada nueva ha­cié­n­do­se cargo de la in­co­r­po­ra­ción de los co­n­te­ni­dos que ya existían.

Hasta aquí hemos escrito una entrada en una base de datos que podemos recuperar en cualquier momento. Uti­li­za­mos para ello el método GET.

GET bibliography/novels/1

Si quieres, tienes la opción de vi­sua­li­zar la entrada en tu navegador:

http://localhost:9200/bibliography/novels/1

En el output, Ela­s­ti­c­sea­r­ch nos muestra todos los detalles de nuestra entrada:

{
	"_index": "bibliography",
	"_type": "novels",
	"_id": "1",
	"_version": 2,
	"found": true,
	"_source": {
		"author": "William Gibson",
		"title": “Count Zero",
		"year": "1984"
	}
}

Sin perjuicio de lo previsto an­te­rio­r­me­n­te, también podrás encontrar los campos del documento en _source. Ela­s­ti­c­sea­r­ch también informa de que se ha en­co­n­tra­do una entrada. Si intentas llamar una entrada in­e­xi­s­te­n­te, no aparecerá un mensaje de error. En su lugar Ela­s­ti­c­sea­r­ch re­s­po­n­de­rá “found”: false, lo que quiere decir que no hay entradas en _source.

También tienes la opción de extraer solo cierta in­fo­r­ma­ción de la base de datos. Su­po­n­ga­mos que no solo has incluido datos bi­blio­grá­fi­cos en tu índice, sino también el texto completo de cada novela grabada. Esta in­fo­r­ma­ción se mostraría con una simple petición GET. Su­po­n­ga­mos, sin embargo, que por el momento solo te interesa el nombre del autor y el título de la obra, entonces puedes pedirlo es­pe­cí­fi­ca­me­n­te:

GET bibliography/novels/1?_source=author,title

Si no estás in­te­re­sa­do en los metadatos de una entrada, también puede mostrar solo el contenido:

GET bibliography/novels/1/_source

Para los casos en los que no deseas llamar una sola entrada en el índice, sino varias, Ela­s­ti­c­sea­r­ch ha im­ple­me­n­ta­do el parámetro _mget (para multi-get). Si utilizas esta opción, es­pe­ci­fi­ca una matriz compuesta de varios ID:

GET bibliography/novels/_mget
{
	"ids": ["1", "2", "3"]
}

Incluso si una entrada no existe todavía, la solicitud completa no falla, sino que se te mostrarán todos los datos exi­s­te­n­tes. En cuanto a los datos que faltan, Ela­s­ti­c­sea­r­ch responde que no ha podido en­co­n­trar­los.

El borrado de una entrada funciona de forma similar a su llamada. En lugar de utilizar GET, sin embargo, se trabaja con DELETE:

DELETE /bibliography/novels/1

En el siguiente mensaje Ela­s­ti­c­sea­r­ch te informa de que ha en­co­n­tra­do la entrada bajo el ID es­pe­ci­fi­ca­do:

{
	"_index": "bibliography",
	"_type": "novels",
	"_id": "1",
	"_version": 5,
	"result": "deleted",
}

El programa también aumenta el número de versión en uno. Hay dos razones para ello:

  1. Ela­s­ti­c­sea­r­ch solo marca la entrada como borrada pero no la elimina del disco duro. La entrada solo des­apa­re­ce­rá en el curso posterior de la in­de­xa­ción.
  2. Cuando se trabaja con índices di­s­tri­bui­dos en múltiples nodos, la gestión detallada de versiones es ex­tre­ma­da­me­n­te im­po­r­ta­n­te. Por lo tanto, Ela­s­ti­c­sea­r­ch marca cada cambio como una nueva versión y también la petición de borrado.

También puedes realizar mo­di­fi­ca­cio­nes solo en un número de versión es­pe­cí­fi­co si lo conoces. Si ya existe una versión más nueva en el clúster que la versión es­pe­ci­fi­ca­da, el intento de mo­di­fi­ca­ción conduce a un mensaje de error.

PUT bibliography/novels/1?version=3
{
"author": "Marcel Proust",
"title": " À la recherche du temps perdu",
"year": "1927"
}

Además, no solo puedes llamar varias entradas a la vez, sino también crear o borrar varias con _bulk. Para esto Ela­s­ti­c­sea­r­ch utiliza una sintaxis li­ge­ra­me­n­te diferente.

POST bibliography/novels/_bulk
{"delete": {"_id": "1"}}
{"create": {"_id": "1"}}
{"author": "Johann Wolfgang von Goethe", "title": "Die Leiden des jungen Werther", "year": "1774"}
{"create": {"_id": "2"}}
{"author": "Umberto Eco", "title": "Il nome della rosa", "year": "1980"}
{"create": {"_id": "3"}}
{"author": "Margaret Atwood", "title": "The Handmaid’s Tale", "year": "1985"}

Cada orden tiene su propia línea. En primer lugar, es­pe­ci­fi­ca la acción que se debe realizar (create, index, update, delete). También hay que es­pe­ci­fi­car qué entrada se desea crear y dónde. Con una in­s­tru­c­ción bulk también es posible trabajar en varios índices. Para hacer esto, debes dejar la ruta de POST vacía y asignar una ruta separada a cada acción. Al crear entradas, también debes es­pe­ci­fi­car un request body en una nueva línea que contendrá el contenido de la entrada. La in­s­tru­c­ción DELETE no requiere ningún request body, ya que se borra toda la entrada.

Hasta ahora siempre hemos dado el mismo contenido en los ejemplos, sin importar el campo que fuera, ya que Ela­s­ti­c­sea­r­ch ha in­te­r­pre­ta­do toda la in­fo­r­ma­ción como una cadena de ca­ra­c­te­res coherente. Sin embargo, esto no siempre es así en todos los campos. Es por eso que Ela­s­ti­c­sea­r­ch pro­po­r­cio­na el mapeo (mapping). Esto determina cómo los al­go­ri­t­mos tienen que in­te­r­pre­tar una entrada. Puedes utilizar el siguiente código para vi­sua­li­zar qué asi­g­na­ción se utiliza ac­tua­l­me­n­te en tu índice:

GET bibliography/novels/_mapping

Todos los campos se asignan a los tipos text y keyword. Pero Ela­s­ti­c­sea­r­ch conoce 6 Core Datatypes e incluso más campos es­pe­cia­les. Los 6 tipos pri­n­ci­pa­les se su­b­di­vi­den pa­r­cia­l­me­n­te en otras su­b­ca­te­go­rías:

  • string: esto incluye tanto text como keyword. Mientras que las palabras clave se co­n­si­de­ran coin­ci­de­n­cias exactas, Ela­s­ti­c­sea­r­ch asume que un texto debe ser analizado antes de que pueda uti­li­zar­se.
  • numérico: Ela­s­ti­c­sea­r­ch reconoce di­fe­re­n­tes valores numéricos, que difieren sobre todo en la extensión. Por ejemplo, mientras que el tipo byte puede tener valores de entre -128 y 127, long tiene un rango de -263 a 263-1.
  • date: una fecha puede es­pe­ci­fi­car­se exac­ta­me­n­te al día o con una hora. También puede es­pe­ci­fi­car­se una fecha en forma de tiempo Unix: segundos o mi­li­se­gu­n­dos desde el 1 de enero de 1970.
  • boolean: los campos fo­r­ma­tea­dos como booleanos pueden tener un valor verdadero o falso.
  • binario: puedes almacenar datos binarios en dichos campos. Para tra­n­s­mi­ti­r­los, utiliza la co­di­fi­ca­ción Base64.
  • range: cómo es­pe­ci­fi­car un rango. Este puede estar entre dos valores numéricos, dos datos o incluso entre dos di­re­c­cio­nes IP.

Estas son solo las ca­te­go­rías pri­n­ci­pa­les que es probable que utilices con más fre­cue­n­cia. Si quieres consultar más tipos, hazlo en la lista Ela­s­ti­c­sea­r­ch do­cu­me­n­ta­tion. Los tipos se di­fe­re­n­cian, sobre todo, en que son de valor exacto (exact-value) o de texto completo (full-text). Ela­s­ti­c­sea­r­ch entiende el contenido del campo como una entrada exacta o como un contenido que debe ser procesado primero. En el curso del mapeo, el análisis (Analyzing) también es im­po­r­ta­n­te. El análisis del contenido se subdivide en to­ke­ni­za­ción y no­r­ma­li­za­ción:

  • To­ke­ni­zi­ng: los tokens in­di­vi­dua­les están hechos de un texto. Estos pueden incluir palabras in­di­vi­dua­les, pero también términos fijos de varias palabras.
  • No­r­ma­li­za­ción: los tokens se no­r­ma­li­zan es­cri­bié­n­do­los todos en mi­nú­s­cu­las y re­du­cié­n­do­los a sus formas de raíz.

Para realizar esta operación, Ela­s­ti­c­sea­r­ch utiliza ana­li­za­do­res. Si incluyes un documento en el índice y has realizado la asi­g­na­ción co­rre­c­ta­me­n­te, todos los co­n­te­ni­dos se incluirán co­rre­c­ta­me­n­te en el índice invertido. Para poder utilizar el mapping, debes crear un índice co­m­ple­ta­me­n­te nuevo. No es posible mapear campos que ya existen.

PUT bibliography
{
	"mappings": {
		"novels": {
			"properties": {
				"author": {
					"type": "text",
					"analyzer": "simple"
				},
				"title": {
					"type": "text",
					"analyzer": "standard"
				},
				"year": {
					"type": "date",
					"format": "year"
				}
			}
		}
}
}

Hemos definido los dos campos author y title como text y, por lo tanto, como full-text (texto completo), de modo que aún necesitan un ana­li­za­dor adecuado. Mientras que pro­po­r­cio­na­mos el ana­li­za­dor estándar para el campo de título de la novela, elegimos el Simple Analyzer, menos complejo, para el nombre del autor. El año de pu­bli­ca­ción, por otra parte, se fija como fecha (date) y, por lo tanto, como valor exacto (exact-value). Dado que Ela­s­ti­c­sea­r­ch asume como formato estándar una es­pe­ci­fi­ca­ción de año, mes y día, debemos cambiar esto, ya que nos gustaría li­mi­tar­nos a es­pe­ci­fi­car solo el año.

Buscar

En el capítulo anterior uti­li­za­mos Ela­s­ti­c­sea­r­ch y su índice como base de datos, pri­n­ci­pa­l­me­n­te. El uso real de Ela­s­ti­c­sea­r­ch, sin embargo, se centra en la búsqueda de texto completo. Esto significa que, en lugar de in­tro­du­cir el ID de un documento y llamar a la entrada, ahora co­n­fi­gu­ra­mos Ela­s­ti­c­sea­r­ch para que pueda buscar es­pe­cí­fi­ca­me­n­te el contenido. Para utilizar el motor de búsqueda, el programa ha pro­po­r­cio­na­do el parámetro _search. Puedes uti­li­zar­lo en co­m­bi­na­ción con el método GET para vi­sua­li­zar todas las entradas, por ejemplo:

GET bibliography/novels/_search
Hecho

Para consultas más complejas, _search utiliza un cuerpo entre corchetes. Sin embargo, algunos se­r­vi­do­res HTTP no prevén esto para el método GET. Es por eso que los de­sa­rro­lla­do­res de­ci­die­ron que tales pe­ti­cio­nes también funcionen como POST.

También puedes dejar la ruta en blanco para buscar en todos los índices exi­s­te­n­tes. En la salida en­co­n­tra­rás la in­fo­r­ma­ción que te interesa en hits:

"hits": {
	"total": 3,
	"max_score": 1,
	"hits": [
		{
			"_index": "bibliography",
			"_type": "novels",
			"_id": "2",
			"_score": 1,
			"_source": {
				"author": "Umberto Eco",
				"title": "Il nome della rosa",
				"year": "1980"
			}
		},
	],
	}
}

Todas las demás entradas en nuestro índice también se enumeran en la salida (y solo se omiten aquí en aras de la claridad). La respuesta de Ela­s­ti­c­sea­r­ch nos pro­po­r­cio­na no solo el contenido real, sino también dos in­fo­r­ma­cio­nes adi­cio­na­les que pueden ayudarnos a entender la búsqueda de texto completo:

  • hits: cada entrada que coincida con los criterios de búsqueda será co­n­si­de­ra­da un éxito por Ela­s­ti­c­sea­r­ch. El programa también muestra el número de aciertos. Como en nuestro ejemplo hay 3 entradas en el índice y todas las mostramos, se considera que son en “total”: 3.
  • score: en forma de pu­n­tua­ción, Ela­s­ti­c­sea­r­ch indica la re­le­va­n­cia de la entrada en relación con nuestra consulta de búsqueda. Dado que en nuestro ejemplo si­m­ple­me­n­te buscamos todos los mensajes, todos tienen la misma pu­n­tua­ción (score) de 1. Las entradas de los re­su­l­ta­dos de la búsqueda están ordenadas por re­le­va­n­cia en orden de­s­ce­n­de­n­te.

En su respuesta Ela­s­ti­c­sea­r­ch también pro­po­r­cio­na in­fo­r­ma­ción sobre cuántos fra­g­me­n­tos (shards) están in­vo­lu­cra­dos en los re­su­l­ta­dos de la búsqueda, cuántos mi­li­se­gu­n­dos tardó la búsqueda y si se produjo un tiempo de espera.

Ela­s­ti­c­sea­r­ch muestra solo los 10 primeros re­su­l­ta­dos de búsqueda de forma pre­de­te­r­mi­na­da. Sin embargo, puedes influir en ello co­n­fi­gu­ra­n­do pa­rá­me­tros:

  • size: ¿cuántos re­su­l­ta­dos debe mostrar Ela­s­ti­c­sea­r­ch?
  • from: ¿cuántas entradas debe omitir el programa antes de mo­s­trar­las?

Si has visto los primeros 10 re­su­l­ta­dos de búsqueda y solo deseas vi­sua­li­zar los 15 si­guie­n­tes, debes utilizar una co­m­bi­na­ción de ambos pa­rá­me­tros:

GET bibliography/novels/_search?size=15&from=10

Ela­s­ti­c­sea­r­ch distingue entre dos tipos de búsquedas di­fe­re­n­tes. Por un lado, utiliza una versión Lite y, por otro, una variante más compleja que funciona con Query DSL, un lenguaje es­pe­cí­fi­co de búsqueda. Con la versión Lite puedes in­tro­du­cir tu consulta como una simple cadena de ca­ra­c­te­res (string) di­re­c­ta­me­n­te en la consulta de búsqueda:

GET bibliography/novels/_search?q=atwood

Sin embargo, también puedes buscar solo dentro de un campo es­pe­cí­fi­co:

GET bibliography/novels/_search?q=author:atwood
Hecho

De hecho, en el primer ejemplo se busca en un campo de­te­r­mi­na­do sin tener que es­pe­ci­fi­car­lo: el campo _all. Si inserta el contenido de un documento en el índice cla­si­fi­ca­do en campos, Ela­s­ti­c­sea­r­ch crea un campo adicional en segundo plano. Todos los co­n­te­ni­dos de los demás campos se almacenan adi­cio­na­l­me­n­te en este campo para permitir dicha búsqueda en todos los campos.

Si deseas combinar varios criterios de búsqueda, utiliza +. El carácter - excluye ciertos criterios. Sin embargo, si utilizas estos ope­ra­do­res, debes utilizar una co­di­fi­ca­ción po­r­ce­n­tual en la consulta de búsqueda:

GET bibliography/novels/_search?q=%2Bauthor%3Aatwood+%2Btitle%3Ahandmaid

La sintaxis de la cadena de consulta de Ela­s­ti­c­sea­r­ch ofrece aún más sutilezas con las que puedes pe­r­so­na­li­zar tu búsqueda. En la Do­cu­me­n­ta­ción de software los de­sa­rro­lla­do­res de Elastic han resumido todos los elementos ese­n­cia­les: enlaces O, frases exactas, campos vacíos o ma­r­ca­do­res de posición.

Esta variante de búsqueda es muy adecuada para consultas sencillas, pero el pro­ce­di­mie­n­to Lite puede fallar rá­pi­da­me­n­te en tareas más complejas: el peligro de in­tro­du­cir un error en la cadena larga es demasiado grande. Por lo tanto, con Query DSL Ela­s­ti­c­sea­r­ch ofrece un método más co­n­ve­nie­n­te. El punto de partida de tal búsqueda es el parámetro de consulta en co­m­bi­na­ción con una consulta de coin­ci­de­n­cia:

GET bibliography/novels/_search
{
	"query": {
		"match": {
"author": "allende"
}
	}
}

El resultado nos muestra todas las entradas que contienen el término “allende” en el campo autor (author). Esto también indica que el análisis en el mapeo funcionó, porque Ela­s­ti­c­sea­r­ch ignora ma­yú­s­cu­las y mi­nú­s­cu­las. Para vi­sua­li­zar todas las entradas, además de la variante que ya se ha explicado an­te­rio­r­me­n­te, también puedes utilizar match_all:

GET bibliography/novels/_search
{
	"query": {
		"match_all": {}
	}
}

Lo contrario de esta búsqueda es match_none. Sin embargo, Ela­s­ti­c­sea­r­ch también te ofrece la po­si­bi­li­dad de buscar en varios campos con un solo término de búsqueda:

GET bibliography/novels/_search
{
	"query": {
		"multi_match": {
			"query": "la",
			"fields": ["author", "title"]
		}
	}
}

Para permitir so­li­ci­tu­des de búsqueda más complejas, también puedes combinar varios términos de búsqueda entre sí y darles un valor diferente. Tienes tres co­n­di­cio­nes a tu di­s­po­si­ción:

  • must: el término debe aparecer.
  • must_not: el término no debe aparecer.
  • should: si aparece este término, la re­le­va­n­cia en los re­su­l­ta­dos de la búsqueda aumenta.

En la práctica, esto se combinará con una consulta booleana:

GET bibliography/novels/search_
{
	"query": {
"bool": {
		"must": {
			"match": {
				"title": "la"
			}
},
		"must_not": {
			"match": {
				"title": "rabbit"
			}
		},
		"should": {
			"match": {
				"author": "allende"
			}
		}
	}
}
}

También puedes ampliar tu búsqueda añadiendo un filtro. Esto te permite es­pe­ci­fi­car los criterios que re­s­tri­n­gen los re­su­l­ta­dos de la búsqueda:

GET bibliography/novels/search_
{
	"query": {
"bool": {
		"must": {
			"match": {
				"title": "la"
			}
},
		"filter": {
			"range": {
				"year": {
					"gte": "1950",
					"lt": "2000"
				}
			}
		}
	}
}
}

En el ejemplo anterior, vi­n­cu­la­mos el filtro a un espectro: solo se mostrarán las entradas pu­bli­ca­das entre 1950 y 2000.

En resumen

Con esta he­rra­mie­n­ta tienes todo a tu di­s­po­si­ción para im­ple­me­n­tar la búsqueda de texto completo para tu proyecto. Sin embargo, Ela­s­ti­c­sea­r­ch ofrece otros métodos para refinar la búsqueda y hacerla más compleja. Puedes encontrar más in­fo­r­ma­ción en la página web oficial de Elastic. Si deseas ampliar más la búsqueda de texto completo, también puede crear tus propios scripts con otros lenguajes como Groovy y Clojure.

Ventajas y de­s­ve­n­ta­jas de Ela­s­ti­c­sea­r­ch

Ela­s­ti­c­sea­r­ch puede llegar a ser una poderosa he­rra­mie­n­ta para la búsqueda de texto completo. Solo se puede culpar a Ela­s­ti­c­sea­r­ch de una cosa y es de la pobre im­ple­me­n­ta­ción de la idea del código abierto. Al margen de esto, la búsqueda de texto completo ofrece numerosas ventajas , también en co­m­pa­ra­ción con el co­m­pe­ti­dor directo Apache Solr.

Ventajas In­co­n­ve­nie­n­tes
Código abierto Elastic como ga­te­kee­per
Rápido y estable
Escalable
Muchos módulos de programa listos para usar (Analyzer, búsqueda de texto completo...)
Fácil im­ple­me­n­ta­ción gracias a Java, JSON y REST-API
Flexible y dinámico
Ir al menú principal