Como primera aproximación a un buscador simple en la primera versión de Voota, se nos ocurrió utilizar “Google custom search“. Mala idea. Hoy, 5 días después de la puesta online, Google solo ha indexado 267 páginas y teniendo en cuenta que empezábamos con 1.549 políticos con sus 1.549 correspondientes fichas, los resultados no eran muy apropiados. Por ejemplo, buscando “Zapatero” aparecían varios resultados del blog, alguna ficha de otros políticos y varios enlaces al ranking, pero no la ficha del sr. presidente.
Necesitábamos un buscador, sencillo, potente y que escalase bien con los futuros desarrollos que vienen. La solución fue mucho más fácil de lo esperado. Decidimos implementar nuestro propio motor de búsqueda con Sphinx. Así es como lo hicimos:
- Lo primero es instalar el motor de búsqueda, que básicamente consta de dos partes: El indexador, que obtiene las palabras clave de la base de datos (Postgresql o mysql) y el demonio o servicio de búsqueda que atiende a las peticiones del servidor web.
La instalación no tiene más misterio que seguir los pasos que explican en su web: Manual de referencia de Sphinx. - Después viene la fase de configuración. Aquí es donde se le dice a Sphinx que datos tiene que indexar para que puedan ser encontrados en el buscador del sitio web. En nuestro caso, de momento, sólo queríamos indexar los políticos:
source src1
{
type = mysql
sql_host = localhost
sql_user = usuario
sql_pass =
sql_db = voota
sql_port = 3306 # optional, default is 3306
sql_query_pre = SET NAMES utf8
sql_query = \
SELECT id, vanity, alias, nombre, apellidos, bio, presentacion, residencia, formacion \
FROM politico
sql_ranged_throttle = 0
sql_query_info = SELECT * FROM politico WHERE id=$id
}
source src1throttled : src1
{
sql_ranged_throttle = 100
}
index politico
{
source = src1
path = /var/data/voota
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
charset_type = utf-8
charset_table = 0..9, A..Z->a..z, a..z, \
U+C0->a, U+C1->a, U+C2->a, U+C3->a, \
U+C4->a, U+C5->a, U+C6->a, \
U+C7->c,U+E7->c, U+C8->e, U+C9->e, \
U+CA->e, U+CB->e, U+CC->i, \
U+CD->i, U+CE->i, U+CF->i, U+D0->d, \
U+D1->n, U+D2->o, U+D3->o, \
U+D4->o, U+D5->o, U+D6->o, U+D8->o, \
U+D9->u, U+DA->u, U+DB->u, \
U+DC->u, U+DD->y, U+DE->t, U+DF->s, \
U+E0->a, U+E1->a, U+E2->a, U+E3->a, \
U+E4->a, U+E5->a, U+E6->a, \
U+E7->c,U+E7->c, U+E8->e, \
U+E9->e, U+EA->e, U+EB->e, U+EC->i, \
U+ED->i, U+EE->i, U+EF->i, \
U+F0->d, U+F1->n, U+F2->o, U+F3->o, \
U+F4->o, U+F5->o, U+F6->o, \
U+F8->o, U+F9->u, U+FA->u, U+FB->u, \
U+FC->u, U+FD->y, U+FE->t, U+FF->s,
html_strip = 0
}Extracto del fichero de configuración de Sphinx
- A continuación se arranca el servicio de búsqueda:
sudo searchd –config /usr/local/etc/sphinx.conf
y se da la orden para que Sphinx realice la indexación (Esto será necesario hacerlo periódicamente):
sudo /usr/local/bin/indexer politico –rotate
Muy bien, Sphinx configurado y escuchando. - Sólo falta escribir el código Symfony para interrogar al motor de búsqueda:
$this->q = $request->getParameter(“q”);$cl = new SphinxClient ();
$cl->SetServer ( ‘localhost’, 3312 );
$this->limit = 1000;
$cl->SetLimits ( 0, $this->limit, $this->limit );
$cl->SetArrayResult ( true );
$this->res = $cl->Query ( SfVoUtil::stripAccents( $this->q ), ‘politico’ );
if ( $this->res!==false ) {
if ( isset($this->res[“matches”]) && is_array($this->res[“matches”]) ) {
$c = new Criteria();
$list = array();
foreach ($this->res[“matches”] as $idx => $match) {
$list[] = $match[‘id’];
}
$c->add(PoliticoPeer::ID, $list, Criteria::IN);
$c->addDescendingOrderByColumn(PoliticoPeer::SUMU);
$this->politicosPager = new sfPropelPager(‘Politico’, 10);
$this->politicosPager->setCriteria($c);
$this->politicosPager->setPage($this->getRequestParameter(‘page’, 1));
$this->politicosPager->init();if ($this->politicosPager->getNbResults() == 1){
$res = $this->politicosPager->getResults();
$this->redirect( “@politico_”.$this->getUser()->getCulture( ‘es’ ).”?id=”.$res[0]->getVanity() );
}
}
}Código Symfony que realiza la búsqueda
Listo, hoy puedes buscar Zapatero, José Luis Rodriguez o ZP en Voota, que seguro que encuentras lo que buscas, a no ser que quieras comprarte unos zapatos nuevos, claro 😉
1 junio 2010 a las 11:59 am
Oooooohhhh!!!! genial.
Gracias Sergio.
Creo que vamos a copiartelo. 😉
1 junio 2010 a las 1:45 pm
¡Genial! Si quieres comentar algo, ya sabes donde estamos 😀
7 julio 2010 a las 4:33 pm
Hola Sergio. Y por qué implementar Lucene mediante este plugin?
http://www.symfony-project.org/plugins/sfLucenePlugin
Un saludo y sigue así, acabo de descubrirte desde symfony.es y la verdad es que el blog y el proyecto de Voota lo encuentro muy interesante.
7 julio 2010 a las 4:40 pm
Hola David, gracias por el comentario.
Lucene es una buena alternativa sin duda. El problema que tiene es que es Java y orientado a Java, mientras que Sphinx se utiliza mucho más con proyectos php (aunque es independiente del lenguaje). Nos gusta estar siempre alineados con el mercado. Siempre es bueno a la hora de buscar ayuda o preguntar a la comunidad 😉
Saludos!
7 julio 2010 a las 5:06 pm
Gracias Sergio. Lo tendré en cuenta cuando lo implemente en mi proyecto. Yo la verdad es que tenía pensado basarme en Zend Lucene para crear un buscador, siguiendo el tutorial oficial:
http://www.symfony-project.org/jobeet/1_4/Doctrine/es/17
Sin embargo, a la vista de tu experiencia (gracias de nuevo por compartirla) consideraré Sphinx (que, la verdad sea dicha, no conocía).
Gracias!
7 julio 2010 a las 5:11 pm
Seguro que ambas opciones son buenas 🙂
Ya nos contarás cual implementas al final y cómo te va. Suerte.
26 septiembre 2010 a las 10:13 pm
Señor! LLego a su web casi por casualidad debido a que estoy en pleno desarrollo de un proyecto en el cual necesitaba hacer uso de un motor de busquedas eficiente..me encuentro con Sphinx pero no tenia idea de quien pudo implementarlo ni como! pero justo encuentro su web!
muchas gracias por compartir esta informacion! no sabe cuan util me ha sido! gracias! exitos!
28 marzo 2011 a las 2:51 pm
Hola sergio, tu clase SphinxClient de donde sale de un plugin?
28 marzo 2011 a las 3:05 pm
Hola Fernando,
No es un plugin, es una de las clases que provee el cliente de Sphinx para php. Puede echar un ojo en el sitio de Sphinx ( http://sphinxsearch.com/wiki/doku.php?id=php_api_docs ) o bajarte directamente la versión que utilizamos en Voota: https://github.com/voota/voota/blob/master/www/lib/sphinxapi.php (que es básicamente lo mismo).
25 junio 2011 a las 1:18 am
Saludos, desde mexico, muy buena explicacion, una duda fuera del tema, la integracion con facebook la hicieron con el Plugin Facebook connect, tengo tiempo liado con el y no he podido echarlo andar, espero me puediras ayudar con el tema