Busquedas Full-Text con MySQL
El asunto es el siguiente…
Supongamos que queremos realizar una búsqueda dentro de una base de datos MySQL, y a la vez esa busqueda en varios campos, establecer prioridades de busqueda, y una serie de customizaciones mas…
Entonces para remplazar al típico operador LIKE vamos a utilizar búsquedas Full-Text.
Para explicar un poco esto… Full-Text es un tipo de indice (KEY o INDEX) que aplicado a distintas columnas permite realizar búsquedas rápidas y precisas sobre estas.
Características generales:
- Es aplicable solamente a campos de tipo CHAR, VARCHAR, o TEXT
- Solo funcionan utilizando el motor MyISAM (Default en la instalacion de MySQL)
- Pueden agregarse cuando se crea una tabla, o directamente ejecutando una consulta para modificar una tabla en particular. Por ejemplo de esta forma
ALTER TABLE nombre_tabla ADD FULLTEXT (campo1, campo2, campoN);
Para utilizar este tipo de búsqueda vamos a usar los operadores MATCH y AGAINST.
Un ejemplo basico seria el siguiente:
SELECT * FROM nombre_tabla WHERE MATCH (campo1, campo2, campoN) AGAINST ('%palabras a buscar%' IN BOOLEAN MODE );
Los operadores que pueden utilizarse en AGAINST para perfeccionar la búsqueda son los siguientes:
-
+
Ejemplo de uso:
'+notebook +lenovo' /* Se obtienen resultados siempre y cuando "notebook" y "lenovo" aparezcan en algun campo en cualquier orden */
-
-
Ejemplo de uso:
'+notebook -lenovo' /* Se obtienen resultados siempre y cuando "notebook" aparezca pero "lenovo" no lo haga */
-
~
Ejemplo de uso:
'+notebook ~lenovo' /* Se obtienen resultados si aparece "notebook" pero es mejor si no aparece "lenovo", en caso de que lo haga el resultado clasifica con menor puntuación que si no lo hiciera */
-
> <
Hacen referencia a la precedencia de una palabra
Ejemplo: (abajo) -
( )
Hace referencia a un conjunto de subexpresiones
Ejemplo de uso:'+notebook +(>lenovo <bangoo)' /* Se obtienen resultados siempre y cuando "notebook" aparezca y tambien aparezcan "lenovo" o "bangoo", pero califica mejor si aparece lenovo que bangoo */
-
*
Hace referencia a cualquier caracter encontrado
Ejemplo de uso:'note*' /* Se obtienen resultados si se encuentran palabras que comiencen con "note" como "notebook", "notepad", etc */
-
“”
Hace referencia a una expresión literal
Ejemplo de uso:'"Notebook Lenovo"' /* Se obtienen resultados siempre y cuando aparezca la frase completa "notebook lenovo" */
-
%
Hace referencia a cualquiera de las palabras de la expresión
Ejemplo de uso:'%Notebook Lenovo%' /* Se obtienen resultados si aparecen cualquiera de las palabras, y mientras mas aparezcan mejor califica el resultado */
Es cuestión de armar las mezclas de estos operadores que necesitemos para lograr resultados mas precisos en nuestras busquedas
Hay que destacar que los resultados en los que mayores coincidencias (y en la mayor cantidad de campos) se hayan encontrado tendrán una puntuación mayor al resto de resultados de la consulta
Una buena forma de ordenar nuestros resultados para poder listarlos de mayor puntuacion a menor es la siguiente
SELECT *, MATCH (campo1, campo2, campoN) AGAINST ('%palabras a buscar%' IN BOOLEAN MODE ) AS puntuacion FROM nombre_tabla WHERE MATCH (campo1, campo2, campoN) AGAINST ('%palabras a buscar%' IN BOOLEAN MODE ) ORDER BY puntuacion DESC;
Para mas informacion consulten la pagina oficial http://dev.mysql.com/doc/refman/5.0/es/fulltext-search.html
Espero que les sirva! Cualquier error que alguien note, comentelo!… porque se me puede pasar!
Saludos!
Buenísimo el aporte, espero que lo aprovechen todos, yo por mi parte lo voy a utilizar en un sistema con BD distribuidas en lan/wan con vb+mysql