Las búsquedas Full-text, las palabras cortas y los hostings compartidos (parte I)
Uno de los problemas de los hostings compartidos es que no podemos configurar a nuestro gusto el software que corre en el sistema. Así, debemos compartir las configuraciones de Apache, ISS, MySql, SqlServer con los demás usuarios de nuestro servidor.
Muchas veces esto no es un problema, y el coste de estos hostings es tan bajo que vale la pena compartir, pero en otras ocasiones nuestra aplicación necesitará requerimientos especiales, y al no poder configurarlos, perderemos efectividad. Una muestra de ello son las búsquedas Full-text.
Ejemplificaré rápidamente a lo que me refiero, supongamos que tenemos un artículo titulado como:
“amantes del ron y las motos”
Un usuario realiza búsquedas a nuestra base de datos del tipo:
“me gusta el ron”, “artículos sobre el ron”, “mi bebida favorita es el ron”
Bajo la configuración estándar de Mysql para búsquedas Full-text, la palabra “ron” es menor o igual a tres caracteres, por lo que la desprecia y decide no incluirla en la búsqueda. Podríamos cambiar este parámetro si tuviéramos acceso al archivo de configuración my.conf … pero … ah! Olvídate de esto pequeño saltamontes, porque tú, estas usando un servidor compartido.
¿Cómo hacer búsquedas con palabras iguales o menores a 3 caracteres?
¡Pues convirtiéndolas en palabras mayores de tres caracteres!
Necesitamos crear una función que alargue estas pequeñas escurridizas en palabras decentes listas para ser encontradas y lo mejor de todo es que estas funciones ya existen! Se tratan de las funciones hash.
A grandes rasgos, las funciones hash generan y retornan claves unívocas a partir de unos datos de entrada, por ejemplo, en forma de una rista de números. Estas funciones se utilizan normalmente para la encriptación y resultarán perfectas para nuestro propósito.
En términos PHP, podríamos usarlas así:
palabra_alargada = hash(“md5”, “ron” )
Retornándonos algo como:
palabra_alargada = 45798f269709550d6f6e1d2cf4b7d485
Quedándose el título del artículo así:
“amantes del 45798f269709550d6f6e1d2cf4b7d485”
En algunas implementaciones podría sernos útil unir el hash a la palabra inicial:
“amantes del ron45798f269709550d6f6e1d2cf4b7d485”
Además, seguramente no necesitamos toda la cadena y podríamos alargar la palabra sólo tres o cuatro caracteres más.
“amantes del ron4579”
En cualquier caso y bajo cualquier implementación ¡ya tenemos una palabra mayor a tres caracteres y que Full-text encontrará cuando la busquemos!
Algunos detalles
Este tipo de funciones suelen ser case sensitive, es decir, la función retornará un hash diferente en función de si la palabra a convertir está o no en mayúsculas, por lo que un detalle importante a tener en cuenta es la de convertir a minúsculas o mayúsculas la palabra antes del proceso de cambio.
Por otro lado, si las búsquedas Full-text tienen el requisito de ignorar estas palabras es por algo. Y es que estadísticamente la mayor parte de las palabras cortas no son relevantes. Así que separar las relevantes “ron, dvd, pes…“ de las que no lo son “mas, con, por…” es desde luego una buena práctica.
¿Cómo lo aplico a mi proyecto?
Con imaginación ya que no existe una sola forma de implementación. Mostraré un ejemplo funcional en la segunda parte del artículo, en cualquier caso, aquí un par de ideas:
- Por ejemplo, manteniendo dos columnas en nuestra base de datos, una con las palabras sin modificar y otra con las palabras alargadas.
- Si no queremos añadir una nueva columna, creando una función recortadora que recorte la porción hash de las palabras antes de presentar el resultado.
¡No te pierdas la segunda parte!
Ummm, no se si este método es muy válido, ¿y si en nuestra base de datos tambien hay caracteres o dígitos que coinciden con la cadena incorporada?… la búsqueda sería una chapucilla:
– Resultado 1: Ron
– Resultado 2: 23
Saludos !
Hola
No guardes “23”, si no “ron45798f269709550d6f6e1d2cf4b7d485” … la probabilidad de que en tus artículos haya una palabra así, es infinitamente inferior a la probabilidad de perder un artículo por el tamaño de sus palabras
Hola.
No puedo creer la coincidencia. 1 día antes estaba en este dilema. Implementé la busqueda con la misma técnica que comentas pero no con la funcion hash sino concatenando una cadena ‘estandar’ que no sea comun para la busqueda (ejm. 0w7, 32x, cosas asi). Al fin y al cabo es la misma idea.
Sin embargo falta un detalle importante: las palabras a las que se le aplica la concatenacion obviamente nunca coincidiran con las stop words. Antes de alargar las palabras deberiamos filtrarlas por las stop words y entonces aplicar la tecnica. Me pasaba eso en la pagina ya que al buscar por ejm “el chavo”, me salia “el chavo” de primer lugar (las busquedas full text tambien ordenan por relevancia), pero tambien la busqueda me arrojaba todos los registros con la palabra “el”. La filtracion de las palabras correctas es importante.
Muy interesante tu articulo, muchas gracias.
Coincido con Mario, es más como parte adicional del artículo deberías hablarnos sobre las stop words.
Hola
Tal y como sugerís, es cierto que apenas comento el concepto de las palabras no relevantes, ya que la finalidad del artículo no era exactamente ese.
Por otro lado, es rápido encontrar ficheros con listas de stop-words en muchos idiomas, en cualquier caso, me apunto la sugerencia para otro artículo.