lunes, 21 de noviembre de 2011

Sphinx en .NET

Sphinx salió al mercado de los motores de búsqueda web hace ya unos años. Y ha conseguido dar un gran impulso a las búsquedas internas de un sitio web.

Para los que no lo conozcan voy a explicar brevemente en que consiste. Sphinx es un motor de búsqueda que te permite indexar cualquier tipo de documentos, por lo general se utiliza para indexar internamente un sitio web. Esto nos permite poder añadir una sección de búsqueda en nuestro sitio web. Sphinx como buen motor de búsqueda, está optimizado para poder indexar gran cantidad de documentos en muy poco tiempo, y además permite efectuar búsquedas en cuestión de milisegundos. La indexación de documentos (particularmente se suele tratar de las distintas URLs de un sitio web) se realiza en modo "Full Text", es decir, se indexa todo el contenido del documento de forma que al buscar una palabra en los documentos de nuestro indice, obtendremos los distintos documentos donde aparece esa palabra (aunque solo sea de pasada).

Bien, vayamos entrado en materia. Sphinx está muy optimizado para PHP y Perl, pero también permite que se pueda utilizar con otros entornos como Java o .NET. Desgraciadamente para .NET no existe una API válida (hay varios intentos no oficiales de implementación, pero por lo general no están completos), no obstante las últimas versiones de Sphinx permiten interactuar con él a través de MySQL lo que se conoce como SphinxQL, que es un lenguaje con la sintaxis de SQL.

Las ventajas de SphinxQL es que permite utilizar las ventajas de Sphinx a través de una interfaz única para todos los lenguajes, puesto casi todos los entornos de programación tienen definido el acceso a las bases de datos MySQL.

No es el objetivo de este artículo el explicar como se instala Sphinx, para eso podéis acceder a la documentación oficial: http://sphinxsearch.com/docs/2.0.2/ sino simplemente explicar como se configura el entorno para poder utilizar SphinxQL a través de .NET

En el archivo de configuración de sphinx (sphinx.conf) especificaremos los siguiente en el apartado del "searchd" (proceso de búsqueda):
searchd
{
 listen = 127.0.0.1:9312
 listen = 127.0.0.1:9306:mysql41  

 mysql_version_string = 5.0.37
 #Resto de configuración de Sphinx
}
Los apartados "listen" configuran el puerto de acceso a Sphinx, el primero será el puerto desde el cual se podrá acceder al protocolo binario de Sphinx (el cual no podemos utilizar con .NET), mientras que el segundo indica el punto de acceso para el protocolo mysql41, el cual se utiliza para SphinxQL.

La última linea es vital, porque le dice al conector de MySQL cuál es la versión que va a utilizar, si no se especifica este valor, el searchd devuelve la versión de Sphinx, desde PHP la versión se maneja bien, pero desde .NET o Java se malinterpreta la versión y nos hace saltar una excepcion.

Una vez configurado el searchd vamos a meternos un poco con el código en .NET. Para ello deberemos tener instalado el conector de MySQL para .NET: http://dev.mysql.com/downloads/connector/net/

Vamos a hacer un listado de los documentos que contengan la palabra "Saberpsicologia":
        Dim con As MySqlConnection = New MySqlConnection("server=127.0.0.1;Port=9306;Charset=utf8;Pooling=false")
        Dim command As MySqlCommand = New MySqlCommand("SELECT * FROM index WHERE MATCH ('Saberpsicologia')", con)

        Try
            con.Open()
            System.Console.WriteLine("Conexion abierta: " + con.ServerVersion + Chr(13))

            Dim reader As MySqlDataReader = command.ExecuteReader()

            Do While reader.Read()
                Dim str As String = String.Empty
                For i As Integer = 0 To reader.FieldCount - 1
                    str += reader.GetString(i) + " "
                Next
                System.Console.WriteLine(str)
            Loop
            con.Close()
        Catch ex As Exception
            System.Console.WriteLine(ex.ToString())
        End Try
Este código buscará en el índice "index" todos los documentos que contengan la palabra Saberpsicología.

Como veis una vez configurado correctamente, que ha sido una labor ardua de investigación, es fácil manejar el SphinxQL, que además de búsquedas nos permitirá indexar documentos en tiempo real, utilizando los "Real Time index".

Para finalizar e ilustrar el ejemplo anterior, os muestro un ejemplo de lo mismo pero para Java:
  try 
  {
   Class.forName("com.mysql.jdbc.Driver");
   Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://127.0.0.1:9306?characterEncoding=utf8","root", "");

   Statement statement = con.createStatement();

   ResultSet resultSet = statement.executeQuery("SELECT * FROM index WHERE MATCH('Saberpsicologia')");

   System.out.println(resultSet.getRow());
   while (resultSet.next()) 
   {
    System.out.println(resultSet.getString(1) + " "
        + resultSet.getString(2) + " "
        + resultSet.getString(3));
   }
   System.out.println("ok!  ");
  } catch (Exception ex) {
   System.out.println(ex.toString());
  }

No hay comentarios:

Publicar un comentario