ElasticSearch, Esfinge, Lucene, Solr, Xapian. ¿Cuál se adapta a qué uso? [cerrado]
Actualmente estoy buscando otros métodos de búsqueda en lugar de tener una consulta SQL enorme. Vi elasticsearch recientemente y jugué con whoosh (una implementación de Python de un motor de búsqueda).
¿Puede darnos los motivos de su(s) elección(es)?
Como creador de ElasticSearch, tal vez pueda darte algún razonamiento sobre por qué seguí adelante y lo creé en primer lugar :).
Usar Lucene puro es un desafío. Hay muchas cosas de las que debes ocuparte si quieres que realmente funcione bien y, además, es una biblioteca, por lo que no hay soporte distribuido, es solo una biblioteca Java integrada que debes mantener.
En términos de usabilidad de Lucene, hace mucho tiempo (hace casi 6 años) creé Compass. Su objetivo era simplificar el uso de Lucene y simplificar el uso cotidiano de Lucene. Lo que encontré una y otra vez es el requisito de poder distribuir Compass. Comencé a trabajar en ello desde Compass, integrándolo con soluciones de cuadrícula de datos como GigaSpaces, Coherence y Terracotta, pero no es suficiente.
En esencia, una solución Lucene distribuida debe fragmentarse. Además, con el avance de HTTP y JSON como API ubicuas, significa que se puede utilizar fácilmente una solución que permite utilizar muchos sistemas diferentes con diferentes lenguajes.
Por eso seguí adelante y creé ElasticSearch. Tiene un modelo distribuido muy avanzado, habla JSON de forma nativa y expone muchas funciones de búsqueda avanzada, todas expresadas perfectamente a través de JSON DSL.
Solr también es una solución para exponer un servidor de indexación/búsqueda a través de HTTP, pero yo diría que ElasticSearch proporciona un modelo distribuido muy superior y facilidad de uso (aunque actualmente carece de algunas de las funciones de búsqueda, pero no por mucho tiempo, y en cualquier caso En este caso, el plan es incorporar todas las funciones de Compass a ElasticSearch). Por supuesto, soy parcial, ya que creé ElasticSearch, por lo que es posible que tengas que comprobarlo tú mismo.
En cuanto a Sphinx, no lo he usado, así que no puedo opinar. Lo que puedo referirte es a este hilo en el foro de Sphinx que creo que demuestra el modelo distribuido superior de ElasticSearch.
Por supuesto, ElasticSearch tiene muchas más funciones además de simplemente distribuirse. En realidad, está construido pensando en la nube. Puede consultar la lista de funciones en el sitio.
He utilizado Sphinx, Solr y Elasticsearch. Solr/Elasticsearch están construidos sobre Lucene. Agrega muchas funciones comunes: API de servidor web, facetado, almacenamiento en caché, etc.
Si solo desea tener una configuración simple de búsqueda de texto completo, Sphinx es una mejor opción.
Si desea personalizar su búsqueda, Elasticsearch y Solr son las mejores opciones. Son muy extensibles: puedes escribir tus propios complementos para ajustar la puntuación de los resultados.
Algunos usos de ejemplo:
- Esfinge: craigslist.org
- Solr: Cnet, Netflix, digg.com
- Búsqueda elástica: Foursquare, Github
Utilizamos Lucene regularmente para indexar y buscar decenas de millones de documentos. Las búsquedas son bastante rápidas y utilizamos actualizaciones incrementales que no llevan mucho tiempo. Nos tomó algo de tiempo llegar hasta aquí. Los puntos fuertes de Lucene son su escalabilidad, una amplia gama de funciones y una comunidad activa de desarrolladores. El uso de Lucene básico requiere programación en Java.
Si está comenzando de nuevo, la herramienta para usted en la familia Lucene es Solr , que es mucho más fácil de configurar que Lucene y tiene casi todo el poder de Lucene. Puede importar documentos de bases de datos fácilmente. Solr está escrito en Java, por lo que cualquier modificación de Solr requiere conocimientos de Java, pero puedes hacer mucho simplemente modificando los archivos de configuración.
También he oído cosas buenas sobre Sphinx, especialmente en combinación con una base de datos MySQL. Aunque no lo he usado.
En mi opinión, debes elegir según:
- La funcionalidad requerida: por ejemplo, ¿necesita una lematizadora francesa? Lucene y Solr tienen uno, no sé los demás.
- Competencia en el lenguaje de implementación: no toque Java Lucene si no conoce Java. Es posible que necesites C++ para hacer cosas con Sphinx. Lucene también se ha adaptado a otros idiomas . Esto es muy importante si desea ampliar el motor de búsqueda.
- Facilidad de experimentación: creo que Solr es mejor en este aspecto.
- Interfaz con otro software: Sphinx tiene una buena interfaz con MySQL. Solr admite interfaces Ruby, XML y JSON como servidor RESTful. Lucene solo le brinda acceso programático a través de Java. Compass e Hibernate Search son contenedores de Lucene que lo integran en marcos más grandes.
Usamos Sphinx en un proyecto de búsqueda vertical con más de 10.000.000 de registros MySql y más de 10 bases de datos diferentes. Tiene un soporte excelente para MySQL y un alto rendimiento en indexación, la investigación es rápida pero tal vez un poco menos que Lucene. Sin embargo, es la elección correcta si necesita una indexación rápida todos los días y utiliza una base de datos MySQL.
Mi esfinge.conf
source post_source
{
type = mysql
sql_host = localhost
sql_user = ***
sql_pass = ***
sql_db = ***
sql_port = 3306
sql_query_pre = SET NAMES utf8
# query before fetching rows to index
sql_query = SELECT *, id AS pid, CRC32(safetag) as safetag_crc32 FROM hb_posts
sql_attr_uint = pid
# pid (as 'sql_attr_uint') is necessary for sphinx
# this field must be unique
# that is why I like sphinx
# you can store custom string fields into indexes (memory) as well
sql_field_string = title
sql_field_string = slug
sql_field_string = content
sql_field_string = tags
sql_attr_uint = category
# integer fields must be defined as sql_attr_uint
sql_attr_timestamp = date
# timestamp fields must be defined as sql_attr_timestamp
sql_query_info_pre = SET NAMES utf8
# if you need unicode support for sql_field_string, you need to patch the source
# this param. is not supported natively
sql_query_info = SELECT * FROM my_posts WHERE id = $id
}
index posts
{
source = post_source
# source above
path = /var/data/posts
# index location
charset_type = utf-8
}
Guión de prueba:
<?php
require "sphinxapi.php";
$safetag = $_GET["my_post_slug"];
// $safetag = preg_replace("/[^a-z0-9\-_]/i", "", $safetag);
$conf = getMyConf();
$cl = New SphinxClient();
$cl->SetServer($conf["server"], $conf["port"]);
$cl->SetConnectTimeout($conf["timeout"]);
$cl->setMaxQueryTime($conf["max"]);
# set search params
$cl->SetMatchMode(SPH_MATCH_FULLSCAN);
$cl->SetArrayResult(TRUE);
$cl->setLimits(0, 1, 1);
# looking for the post (not searching a keyword)
$cl->SetFilter("safetag_crc32", array(crc32($safetag)));
# fetch results
$post = $cl->Query(null, "post_1");
echo "<pre>";
var_dump($post);
echo "</pre>";
exit("done");
?>
Resultado de muestra:
[array] =>
"id" => 123,
"title" => "My post title.",
"content" => "My <p>post</p> content.",
...
[ and other fields ]
Tiempo de consulta de la esfinge:
0.001 sec.
Tiempo de consulta de Sphinx (1k simultáneo):
=> 0.346 sec. (average)
=> 0.340 sec. (average of last 10 query)
Tiempo de consulta MySQL:
"SELECT * FROM hb_posts WHERE id = 123;"
=> 0.001 sec.
Tiempo de consulta MySQL (1k simultáneo):
"SELECT * FROM my_posts WHERE id = 123;"
=> 1.612 sec. (average)
=> 1.920 sec. (average of last 10 query)