Indexar las búsquedas full-text con Sphinx. Tutorial como usar Sphinx
¿Cómo realizar búsquedas full-text en una tabla con miles o millones de registros, sin que el mysql falle y el site siga siendo relevante y no se caiga?
La solución se llama Sphinx.
Es un motor de búsqueda (search engine) que proporciona velocidad, gran eficiencia y proporciona a aplicaciones y webs la función de búsquedas full-text relevantes.
Básicamente lo que hace es indexar todo el contenido de una tabla, o varias tablas, en el disco duro, cuando se realiza una búsqueda el servidor requiere espacio en disco duro y memora RAM para realizar la búsqueda. Al tenerla indexada es capaz de procesar una búsqueda full-text en 6GB de texto en 0.1 segundos, mientras que esto en SQL sería imposible o tardaría muchísimo.
Tremendo descubrimiento…. recomiendo usarlo
Bueno esto es algo de la teoría, la práctica es otra cosa, yo he estado 2 días para entender, implementar y dejarlo funcionando.
Para poder instalarlo necesitareis tener permisos como root en vuestro servidor. Las librerías necesarias son mysql-devel y los compiladores gcc y g++. En el caso que no vengan instaladas ejecutar los siguientes comandos para descargar los paquetes e instalarlos.
- $ yum -y install mysql-devel
- $ yum -y install gcc
- $ yum -y install g++
En otras versiones de linux para descargar e instalar éstas librerías es apt-get.
Ahora descargamos la última versión de Sphinx Descomprimimos el .tar.gz, una vez dentro del directorio de Sphinx:
- Arrancamos la configuración del programa: $ ./configure , la cual chequea los compiladores que tienes instalados y las librerías necesarias.
- Construimos los binarios: $ make
- Instalamos los binarios (por defecto se instalan en /usr/local/bin/): $ make install
Para mas información: http://www.sphinxsearch.com/docs/current.html#installation
Instalar las librerías y el software Sphinx no es el problema. El tema es configurarlo, configurar sphinx.conf
En el archivo de configuración consta de las siguientes partes:
- El source xxxx : Es la conexión a la base de datos que tiene que hacer, especificar una tabla con todos sus campos y asignar los campos de fecha (sql_sttr_timestamp) y un campo identificador denominado (sql_sttr_unit) . xxx es el nombre que le damos a nuestro source.
- El index xxxx: Especificamos que es lo que queremos indexar. xxx será el nombre de nuestro indexar, al cual llamaremos posteriormente por consola para indexar el contenido o lo llamaremos con la API que tiene de PHP. source = xxx. Es el source que tiene que usar el index para conectarse a la base de datos e indexar. path = especificamos el path donde queremos guardar los archivos físicos de indexación.
- El indexer Es la configuración específica del indexador, se le pueden asignar valores para la cantidad de memoria que puede usar,etc..
- El searchd Es el demonio que se ejecuta para que quede a la escucha de las búsquedas que hacemos y las peticiones que se realizan desde la API. Tiene una serie de parámetros de configuración. Se pueden especificar una serie de path para los logs que genera, pero lo mas importante es asignar el puerto de escucha, por defecto 9312.
Ejemplo de mi sphinx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
source busquedas
{
type = mysql
sql_host = localhost
sql_user = mi_user
sql_pass = xxxxx
sql_db = mi_basededatos
sql_port = 3306
sql_query =
SELECT id, categorias, provincia, titulo, contenido, fecha
FROM busqueda
sql_attr_uint = id
sql_attr_timestamp = fecha
sql_query_info = SELECT * FROM busqueda WHERE id=$id
}
index busquedasx
{
source = busquedas
path = /mi_path/sphinx/busquedas1
docinfo = extern
charset_type = sbcs
}
indexer
{
mem_limit = 32M
}
searchd
{
listen = 127.0.0.1
port = 3312
log = /var/log/sphinx/searchd.log
query_log = /var/log/sphinx/query.log
read_timeout = 5
max_children = 30
pid_file = /var/log/sphinx/searchd.pid
max_matches = 1000
seamless_rotate = 1
preopen_indexes = 0
unlink_old = 1
crash_log_path = /var/log/sphinx/crash
}
indexar el contenido
/usr/bin/indexer –config /usr/local/etc/sphinx.conf –all aparecerá por pantalla: Sphinx 0.9.8-rc2 (r1234) Copyright (c) 2001-2008, Andrew Aksyonoff
using config file ‘/usr/local/etc/sphinx.conf’… indexing index ‘busqueda’… collected 1807 docs, 1.0 MB sorted 2.5 Mhits, 100.0% done total 1807 docs, 1004609 bytes total 1.456 sec, 689957.88 bytes/sec, 1241.03 docs/sec
Buscar
/usr/bin/search –config /usr/local/etc/sphinx.conf cumpleaños Sphinx 0.9.8-rc2 (r1234) Copyright (c) 2001-2008, Andrew Aksyonoff
using config file ‘/usr/local/etc/sphinx.conf’… index ‘busqueda’: query ‘cumpleaños’: returned 87 matches of 87 total in 0.000 sec
displaying matches: aquí aparecerá un array con todas los elementos que han coincidido
Lanzar el demonio
/usr/bin/searchd –config /usr/local/etc/sphinx.conf
Un código PHP de ejemplo que integra Sphinx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
include('sphinxapi.php');
$cl = new SphinxClient();
$cl->SetServer( "localhost", 3312 );
$cl->SetMatchMode( SPH_MATCH_ANY );
// el primer parámetro es la query, es lo que queremos buscar: cumpleaños
// el segundo parámetro es el index que vamos a usar para buscarlo
$result = $cl->Query( 'cumpleaños', 'busqueda' );
if ( $result === false ) {
echo "fallo en Query: " . $cl->GetLastError() . ".n";
}
else {
if ( $cl->GetLastWarning() ) {
echo "WARNING: " . $cl->GetLastWarning() . "
";
}
if ( ! empty($result["matches"]) ) {
foreach ( $result["matches"] as $doc => $docinfo ) {
echo "$docn";
}
print_r( $result );
}
}
exit;
?>
Esto es solo un tutorial detallando cada paso de la instalación e implementación. Hay otros parámetros que se pueden configurar pero son opcionales. Recomiendo lean el manual completo: http://www.sphinxsearch.com/docs/current.html.