Indexar las búsquedas full-text con Sphinx. Tutorial como usar Sphinx

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


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

<?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.

Tags de búsquedas:

sphinx tutorial, sphinx php, instalar sphinx, agrupar sphinxclient, sphinx telnet interface, sphinx fulltext, sphinx ejemplos, instalar sphinx windows, instalar sphinx para windows, indexacion local linux

Posts Relacionados:


Te ha ayudado el artículo? Colabora!

25 comentario/s

Comentar

  1. Olga dice:

    Hola!

    Estoy intentando ordenar los resultados de las búsquedas hechas en sphinx por medio de un campo tipo timestamp incluido en la consulta del índice, poniendo: “$cl->SetSortMode(SPH_SORT_ATTR_ASC, “fechaadicion”);…pero no funciona..¿qué estoy haciendo mal?

    Gracias

    • Pedro Ventura dice:

      En el archivo de configuración que has puesto en sql_query ?

      • Olga dice:

        sql_query = SELECT idHotel, nombre, cadena, estrellas, empresario, localizacion, direccion, provincia, telefono, fax, web, rango_precios, longitud, latitud, fechaadicion FROM hoteles

        • Pedro Ventura dice:

          Me has dicho que fechaadiccion es un campo timestamp,no? tipo: 1196440210, sino tendrías que poner lo siguiente, para convertirlo a timestamp

          SELECT idHotel, nombre, cadena, estrellas, empresario, localizacion, direccion, provincia, telefono, fax, web, rango_precios, longitud, latitud, UNIX_TIMESTAMP(fechaadicion) FROM hoteles

          sql_attr_timestamp = fechaadicion

          Otra cosa:

          Intenta declarar el campo fechaadicion como un atributo

          sql_attr_uint = fechaadicion

          Que setMatchMode estas usando?

          • Olga dice:

            Hola!

            Pues mira, el SetMatchMode que estoy usando es:
            $cl->SetMatchMode(SPH_MATCH_ANY);

            En cuanto al tipo del campo “fechaadicion”, lo declaré en phpmyadmin como “timestamp”, pero veo los datos guardados del siguiente modo:
            2012-04-21 19:38:22

            Entonces..si quiero que me ordene los datos por la fecha de inclusión (fechaadicion), tengo que declarar el campo “fechaadicion” como sql_attr_uint o sql_attr_timestamp, o ambos?

            Muchas gracias por responder

          • Pedro Ventura dice:

            Prueba el MatchMode: SPH_MATCH_EXTENDED2

            Por otro lado prueba a transformar la sql como te dije antes SELECT idHotel, nombre, cadena, estrellas, empresario, localizacion, direccion, provincia, telefono, fax, web, rango_precios, longitud, latitud, UNIX_TIMESTAMP(fechaadicion) FROM hoteles
            para devolver un integer, el timestamp de la fecha

            luego para el sql_attr_uint o sql_attr_timestamp, prueba ambos. Creo que puede poner ambos el sphinx.conf

          • Olga dice:

            Hola Pedro,

            muchas gracias por responder. Pues te explico, cómo me dijiste, puse el MatchMode: SPH_MATCH_EXTENDED2.

            En sphinx.conf:
            sql_query_pre = SET NAMES utf8
            sql_query_pre = SET SESSION query_cache_type=OFF

            sql_query = \
            SELECT idHotel, nombre, cadena, estrellas, empresario, localizacion, direccion, provincia, telefono, fax, web, rango_precios, longitud, latitud, UNIX_TIMESTAMP(fechaadicion) \
            FROM hoteles

            sql_ranged_throttle = 0

            sql_attr_uint = UNIX_TIMESTAMP(fechaadicion)

            sql_query_info = SELECT * FROM hoteles WHERE idHotel=$id

            Y el resultado cuando hago la búsqueda es:

            Fallo en Query: index hotelx: sort-by attribute ‘fechaadicion’ not found.

            Probé a poner “fechaadicion” como sql_attr_uint, sin agregarle el UNIX_TIMESTAMP y daba error tb. Lo mismo ocurre con sql_attr_timestamp.

            De cualquiera de las formas, al intentar indexar, me da un warning y me dice que no encuentra esos atributos, incluso con el “idHotel” pasa lo mismo….¿qué será lo que estoy haciendo mal?

  2. leogar07 dice:

    Hola, caigo tarde al tema jaja. Muy buena guia, yo lo hice en windows 7 y wamp. Y ya que estamos, el problema del sphinxclient not found se debe a que ponen en el include del php simplemente sphinxapi.php en vez del path completo (‘C:\sphinx\api\sphinxapi.php’). Mi pregunta es como hago para “ejecutar” el php ya que lo abro en wamp y la pagina se encuentra en blanco. Otra pregunta, el port que pongo en setserver en el php es el mismo que pongo en el port de searchd en el sphinx.conf (3312)?
    Muchas gracias por adelantad0!!

    • leogar07 dice:

      Listo ya lo solucione!! Jaja no funcionaba porque la linea de localhost en el archivo host de los drivers de windows esta comentada. Simplemente se borra el numeral y funciona correctamente. Aviso, esto soluciona el error=10060 que aparece en el command prompt y que hacia que la pagina estuviera en blanco cuando lo abria en localhost. En fin espero haber ayudado a alguien, para mas errores usuales de sphinx-windows les recomiendo http://www.yavarhusain.blogspot.com/, ahi fue donde encontre mi solucion!!

  3. Karla Perez dice:

    Hola Pedro, he estado leyendo tu blog y me he encontrado con cosas muy buenas sobre sphinxs que me han ayudado mucho, y aprovechandome de ti a ver si me podrias ayudar con el siguiente problema: ya tengo implementada la búsqueda con sphinxs en un sistema, el problema que presento es como es que realiza las búsquedas, por ejemplo si yo busco “MIGUEL HERNANDEZ” me encuentra todas las coincidencias pero si escribo “MIGUEL HERNANDE” (sin la z al final) no me trae ninguna coincidencia , y yo quisiera que me presentara un resultado de esta manera:

    MIGUEL HERNANDEZ
    MIGUEL HERNANDES
    (como un tipo like)
    y no lo hace, lo cual me representa un problema bastante fuerte ya que muchas veces como no saben escribir el nombre o el apellido lo escriben a medias para poder localizarlo, y escrito de esa manera Sphinx no encuentra ninguna coincidencia, ya he probado al cambiar los parámetros de forma de búsqueda, por default esta SPH_MATCH_ALL y ya lo cambie por SPH_MATCH_ANY pero esto lo que hace es solo traerme todos los MATCHES por cada palabra que ingreso y en la búsqueda que realizo me trae muchos “MIGUEL” pero ningún “HERNANDE(S/Z)”, espero me halla dado a entender, y gracias anticipadas.

  4. Christian Ceballos dice:

    Buenas tardes ya tengo configurado sphinx pero quisiera saber si alguien alguna vez ha tenido que hacer algo como…. Mostrar tantos resultados por pagina, ósea que en un combo hayan opciones y según la que elijan, muestre ese numero de resultados por pagina porque no tengo idea por donde empezar. Gracias.

  5. Efectivamente, esta empresa es importante, tiene como clientes a Craiglist, WordPress y muchos mas. De hecho, ellos destacan en su pagina comoo 300 bastante conocidos, pero hay muchos mas.

  6. Robbin dice:

    Exelente solucion, me he pasado dias buscando alguna forma de realizar consultas a millones de registros.. me he leido todo, pero aun me queda una duda!

    Como muestra los resultados?
    yo tengo un script que tiene como funcion buscar entre muchos miles de registros!

    y necesito ordenar las busquedas por ID ó por Nombre etc..

    eso es flexible? supongamos en en la tabla tenga
    ID, NOMBRE, EDAD, CIUDAD, DESCRIPCION

    y el resultado necesesite ordenarlo con codigos html para que quede:
    NOMBRE——————————-EDAD
    DESCRIPCION (Ciudad)

    la forma en que lanza los resultados donde se edita?
    ó acaso lanza un texto plano?

    • Pedro Ventura dice:

      Hola Robbin!

      Por un lado tienes toda la indexación de tu base de datos, que es básicamente de lo que hablo en mi artículo y por otro lado tienes que usar la API de Sphinx para obtener los resultados indexados, yo he hecho una breve introducción con un pequeño fragmento de PHP para demostrar como se usa.

      Es en este momento, cuando usas la API, cuando puedes ordenar, filtrar, agrupar,etc… Como utilizar la API de Sphinx no es algo que se pueda explicar en una frase en un comentario te sugiero que le eches un ojo a su docu http://sphinxsearch.com/docs/manual-0.9.9.html#api-reference y vayas analizando como usarla para lo que tu necesitas.

      Si aún tienes más dudas, pregúntame algo en concreto.

      Un saludo!

  7. Pablo dice:

    Hola otra vez Pedro,

    estoy viendo que hablan de recompilar sphinx una vez instalado el libstemmer. El problema que yo las pruebas en local las hago bajo windows… ¿Alguna idea de como realizar esta operación?

    Un saludoy gracias de nuevo!

  8. Pablo dice:

    Buenas Pedro!!

    muchas gracias por el manual, muy bueno y creo que me va a ser de gran ayuda. Pero tengo un par de dudas a ver si me las podrías responder…

    1.- Estoy buscando en una tabla de empresas donde por cada empresa tengo un campo ‘tags’ donde se intenta describir mediante tags la actividad de la empresa. (Ej. Abanicos, agendas, albumes, alfombras). El problema es que si me escriben alguno de los tags en singular no me encuentra a esta empresa.

    2.- Parece que hay un límite a 20 registros por búsqueda ¿alguna idea de como ampliarlo?

    Un saludo y muchas gracias de antemano! :)

  9. Juan dice:

    Gracias por tu manual realize la instalación, configuración, indexación, busqueda y puesta en marcha del “demonio” todo en Windows :p Ahora al momento de querer correr el ejemplo en PHP utilizando xampp me sale el siguiente error: Fatal error: Class ‘SphinxClient’ not found in C:\xampp\htdocs\ejemplo\ej1.php on line 3
    Si puedes ayudarme te lo agradecere mucho
    Saludos y Gracias

    • Pedro Ventura dice:

      Buenas,
      Genial!!! pues has hecho LO MÁS DIFÍCIL!!
      A lo mejor ya te lo has descargado, pero en este enlace podrás descargar la última versión estable de sphinx http://www.sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz
      En la carpeta api está el archivo que tienes que incluir sphinxapi.php, prueba a usar los ejemplos que hay en la carpeta, test.php y test2.php a ver si éstos ejemplos te funcionan bien y no te dan errores,ok?!
      Un saludo!

Deja tu comentario

Nombre:

Email (no será publicado)

Website

Comentario

Colabora, añade +1 a mi blog!!