Generalmente cuando queremos buscar una palabra o expresión mediante coincidencias en MySQL utilizamos LIKE (‘%palabra%’), en caso que estamos buscando más de una palabra usamos LIKE ‘%palabra1%palabra2%’, pero lo que muchos no sabes es que esta forma de buscar le toma mucho tiempo al motor de base de datos encontrar los resultados y precisamente para eso es que se utiliza FullText Index que en síntesis es un índice para búsquedas sobre campos de texto solamente.. la sintaxis es fácil, MATCH() … AGAINST(), donde MATCH se utiliza para especificar el nombre de la columna que estamos buscando y AGAINST para describir la palabra que se desea encontrar..
Pasemos al ejemplo para comprender mejor como funciona, entonces vamos a crear una tabla llamada.. no sé .. (libros) que tiene un índice de búsqueda de texto para los campos titulo y descripción.
CREATE TABLE IF NOT EXISTS libros ( id INT NOT NULL AUTO_INCREMENT , titulo VARCHAR(50) NOT NULL , descripcion TEXT NOT NULL , PRIMARY KEY (id) , FULLTEXT INDEX Buscar (titulo ASC, descripcion ASC) ) ENGINE = MyISAM; |
Y ahora insertemos unos cuantos registros para hacer las pruebas.
INSERT INTO libros (titulo, descripcion) VALUES ('NodeJS para principiantes', 'Aprende como construir una aplicación web completa con Javascript.'), ('Descubriendo NodeJS', 'Está pensado para personas que tengan algo de conocimiento de JavaScript.'), ('Mastering NodeJS', 'Node is an exciting new platform developed by Ryan Dahl.'), ('Node para frontenders', 'Si tu sabes como usar JavaScript en el navegador...'), ('Descubriendo Node y Express', 'La mayoría de la gente quería ver algo de Node.js y Express..'); |
Y ahora vamos a probarlo y ver que tal funciona.
mysql> SELECT * FROM libros WHERE MATCH(titulo, descripcion) AGAINST ('node'); Empty set (0.00 sec) |
🙁 Hey, podrían pensar que algo anda mal aquí, pero no es así.. por defecto, MySQL utiliza el modo de lenguaje natural (IN NATURAL LANGUAGE MODE), lo que indica que si la palabra buscada existe en más del 50% de los resultados, la salida de la consulta sería básicamente que no existen coincidencias (digamos que evita consultas genéricas).
Entonces haciendo nuevamente la búsqueda, ahora cambiando el modificador hacia “IN BOOLEAN MODE” podremos evitar esa restricción.
mysql> SELECT * FROM libros WHERE MATCH(titulo, descripcion) AGAINST ('node' IN BOOLEAN MODE); +----+-----------------------------+-----------------------------------------------------------------+ | id | titulo | descripcion | +----+-----------------------------+-----------------------------------------------------------------+ | 3 | Mastering NodeJS | Node is an exciting new platform developed by Ryan Dahl. | | 4 | Node para frontenders | Si tu sabes como usar JavaScript en el navegador... | | 5 | Descubriendo Node y Express | La mayoría de la gente quería ver algo de Node.js y Express.. | +----+-----------------------------+-----------------------------------------------------------------+ 3 rows in set (0.00 sec) |
El uso del modificador booleano (IN BOOLEAN MODE) también nos permite utilizar algunos operadores que nos ayudan a hacer nuestras búsquedas más efectivas, como por ejemplo la siguiente consulta, que es similar a la anterior, pero con la mínima diferencia de que ahora estoy buscando libros que contengan node, pero no javascript.
mysql> SELECT * FROM libros WHERE MATCH(titulo, descripcion) AGAINST ('+node -javascript' IN BOOLEAN MODE); +----+-----------------------------+-----------------------------------------------------------------+ | id | titulo | descripcion | +----+-----------------------------+-----------------------------------------------------------------+ | 3 | Mastering NodeJS | Node is an exciting new platform developed by Ryan Dahl. | | 5 | Descubriendo Node y Express | La mayoría de la gente quería ver algo de Node.js y Express.. | +----+-----------------------------+-----------------------------------------------------------------+ 2 rows in set (0.00 sec) |
La información completa sobre este operador (IN BOOLEAN MODE) está en la documentación de MySQL.
Happy Coding…