¿Como hacer un buscador con PHP y MySQL?

En este artículo explicaré como se puede hacer un buscador basado en MySQL y PHP, usando la siguiente biblioteca de mi autoría: https://github.com/PedroUrday/mysql-search-php.

El tipo de búsquedas que realiza está biblioteca es muy básico; las búsquedas son por palabras y no por frases (quizás en la próxima versión lo soporte), y se queda corto en muchos aspectos con respecto a otras herramientas. Si se quiere algo serio, lo mejor es utilizar herramientas especializadas, como Apache Lucene o ElasticSearch. Pero, la ventaja de esta biblioteca es que se puede usar en cualquier servidor de hosting que soporte PHP y MySQL, o sea, la mayoría.

Requisitos:

  • Tener conocimientos básicos de programación en PHP.
  • Tener conocimientos básicos del lenguaje SQL.
  • Tener instalado y saber usar algún gestor de base de datos para MySQL, tales como PHPMyAdmin o Adminer (https://www.adminer.org/).
  • Tener PHP 7+ instalado.
  • Tener MySQL instalado.
  • Tener una tabla de MySQL con al menos un indice de tipo Full Text Search en alguno de sus campos (el o los campos que se usen como criterio de búsqueda).
  • Tener el gestor de dependencias Composer instalado.
  • Tener las siguientes bibliotecas instaladas usando Composer:
    • voku/portable-utf8
    • wamania/php-stemmer
    • voku/stop-words

Como instalar Composer:

Para instalar Composer, debemos ingresar a su sitio oficial: https://getcomposer.org/

Si estamos usando el sistema operativo Windows, podemos descargar un instalador que nos facilitara mucho la instalación. El enlace directo es: https://getcomposer.org/Composer-Setup.exe

Si nuestro sistema operativo no es Windows, podemos seguir los pasos mencionados en https://getcomposer.org/download/, en la sección: "Command-line installation". Además, existen guías en Internet de como instalar Composer en Linux de manera global (system wide); es solo cuestión de buscar.

Como instalar las dependencias:

Una vez instalado Composer, procedemos a instalar las dependencias.

Abrimos una consola de comandos o tambien llamada terminal. (Si estamos usando Windows, abrimos la carpeta del proyecto y presionamos la tecla SHIFT + click derecho en un espacio en blanco de la carpeta y en el menú que aparece hacer click en “Abrir ventana de comandos aquí”).

Escribimos los siguientes comandos:

composer require voku/portable-utf8
composer require wamania/php-stemmer
composer require voku/stop-words

En la carpeta del proyecto se creará una carpeta llamada “vendor“.

Teniendo instaladas las bibliotecas y para poder utilizarlas, debo agregar la siguiente linea de código al principio de cualquier script PHP que valla a hacer uso de estas:

require 'vendor/autoload.php';

Como usar:

Primero debemos descargar y descomprimir la biblioteca. El link directo es: https://github.com/PedroUrday/mysql-search-php/archive/v1.0.zip

Para poder explicar el uso de esta biblioteca, lo haré con un ejemplo:

Tengo un proyecto para un sistema de gestión bibliotecaria. El proyecto lo vamos a desarrollar con PHP y MySQL.

Tenemos creada una base datos MySQL que contiene una tabla llamada ‘libros‘.

Uno de los campos de la tabla es ‘titulo‘ y esta indexado con un indice de tipo Full Text Search.

En una parte del proyecto, necesitamos programar un buscador de libros por titulo.

Para eso, creo un archivo llamado “buscar-libros.php” y agrego las lineas de código necesarias para cargar todas las dependencias, incluida esta biblioteca.

Luego creo una instancia de la clase “Search“:

$search = new Search();

Le asigno el objeto manejador de base de datos ($dbh), que puede ser una instancia de PDO (PHP Data Objects) o MySQLi:

$search->setDatabaseHandler($dbh);

Lo que queremos buscar son libros. Un libro puede estar escrito en cualquier idioma. Pero en este caso buscamos libros en español.

Entonces, asigno el idioma de búsqueda a español:

$search->setLang('es');

Luego sabemos que el texto del titulo de un libro, generalmente, es una oración que contiene palabras sin significado como artículos, pronombres, preposiciones, etc. Esas palabras se llaman “palabras vacías” (https://es.wikipedia.org/wiki/Palabra_vac%C3%ADa) y si las incluimos en la búsqueda, obtendremos resultados de búsqueda que no son significantes en lo que estamos buscando.

Podemos quitar esas palabras de la búsqueda:

$search->setRemoveStopWords(true);

También, puedo eliminar las palabras de corta longitud (menos de 3 caracteres):

$search->setMinWordLength(3);

El titulo de un libro puede contener sustantivos que no son propios, es decir, sustantivos que no son nombres de personas o lugares.

Un ejemplo de este tipo de sustantivos son las palabras que tienen la raíz present, es decir, todas las que tienen ese prefijo y son: presentar, presentarla, presentarlas, presentarle, presentarles, presentarlo, presentarlos, presentarse, presentase, presentásemos, presente, presentémonos, presentable, presentables, presentación, presentaciones, presentado, presentador, presentadores, presentándonos, presentáramos y presentaríamos

Puedo aplicarle a cada una de las palabras del título un algoritmo de stemming (https://es.wikipedia.org/wiki/Stemming), para reducir esas palabras a su raíz y obtener mejores resultados de búsqueda:

$search->setDoStemming(true);

Luego, indico la tabla y el/los campos que voy a usar para la búsqueda:

$search->setTableName('libros');
$search->setFieldsToMatch('titulo');

Si quisiera buscar también por el campo ‘autor‘ (previamente indexado como Full Text Search), se haría de la siguiente manera:

$search->setFieldsToMatch('titulo', 'autor');

También debo indicar los campos que quiero obtener en los resultados. Si quiero obtener todos los campos:

$search->setFieldsToFetch('*');

O, por ejemplo, los campos ‘titulo‘, ‘autor‘, ‘nro_ejemplares‘, ‘nro_edicion‘:

$search->setFieldsToFetch('titulo', 'autor', 'nro_ejemplares', 'nro_edicion');

La biblioteca, realiza paginación de los resultados de búsqueda, por lo que debo indicar la cantidad de resultados por página y la página que quiero obtener. Por ejemplo, quiero obtener 20 resultados de la página 3, sería así:

$search->setMaxResultsPerPage(20);
$search->setPageNumber(3);

Por ultimo, ejecuto la búsqueda indicando el “texto de búsqueda“, que en este caso es el título (en la variable $query):

$info = $search->exec($query);

La variable $info contiene un objeto con las siguientes propiedades:

  • currentPage: El número de página de los resultados devueltos y es el que indique en los parámetros búsqueda
  • totalPages: La cantidad de páginas en total de la búsqueda
  • totalResults: La cantidad de resultados (registros) en total y que no es el de la página devuelta.
  • results: El arreglo que contiene los resultados de búsqueda de la página devuelta.

Si el script es llamado desde una petición AJAX, puedo enviar los resultados de la siguiente manera:

header('Content-Type: application/json');
print json_encode($info);
exit();

En este ejemplo, vimos como hacer un buscador de libros por título, pero ¿que pasa si queremos buscar, además de por titulo, por fecha de publicación?

El campo ‘fecha_publicacion‘ en la tabla ‘libros‘, no esta indexado con un indice Full Text Search, sino con un indice “común y corriente”.

Queremos buscar libros con fecha de publicación posterior al valor de la variable $fecha_publicacion_desde.

Entonces, podemos agregar la siguiente linea antes de ejecutar la búsqueda:

$search->addParams('fecha_publicacion > ?', $fecha_publicacion_desde);

El primer argumento del método addParams, es parte de una sentencia SQL de tipo SELECT, que es construida como una sentencia preparada (prepared statements) por la biblioteca antes de realizar la búsqueda. Específicamente es parte de la clausula WHERE y tiene la misma sintaxis. Se puede agregar mas de un parámetro de búsqueda utilizando AND o OR.

Los siguientes parámetros representan cada uno de los valores indicados con el símbolo ?, propio de las sentencias preparadas.

Con todo esto, también, podemos implementar nuestro propio buscador para nuestro sitio web, sin depender de herramientas avanzadas que no están soportadas en todos los servidores de hosting. Es solo cuestión de probar.

Y eso es todo.

Saludos!

¿Como modularizar proyecto VueJS sin la necesidad de compilar?

Deja un comentario

Your email address will not be published / Required fields are marked *