Skip to content

Instantly share code, notes, and snippets.

@mrroot5
Last active November 17, 2015 09:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrroot5/5b2dc88998f31040b0b4 to your computer and use it in GitHub Desktop.
Save mrroot5/5b2dc88998f31040b0b4 to your computer and use it in GitHub Desktop.
MATCH AGAINST |FULLTEXT Index, buscar en mysql.
# EXPLICACIÓN DE MATCH AGAINST
* Requiere FULLTEXT INDEX para funcionar y tablas MyISAM, o InnoDB a partir de MySQL 5.6.
En MyISAM usan "ft_min_word_len" para controlar el mínimo de palabras mientras que en innoDB se usa "innodb_ft_max_token_size"
docu: http://dba.stackexchange.com/questions/76653/match-against-one-character-words-returns-empty-rows-with-ft-min-word-len-1
official docu: http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_ft_min_token_size
* MATCH son los campos por los que buscaremos en la base de datos (bd). Si usamos campos inviduales estos deben tener cada uno un FULLINDEX de lo contrario debes ponerle FULLINDEX conjuntos.
MATCH solamente por los campos de una única tabla aunque hagamos JOIN de varias.
* AGAINST contiene la cadena a buscar. Existen 3 modos de búsqueda:
1. Natural (defecto): busca palabras concretas dentro de los campos de la bd.
2. Boolean: permite búsquedas concretas en base a los datos que nos interesen (https://dev.mysql.com/doc/refman/5.0/en/fulltext-boolean.html).
3. Query extension: realiza una primer búsqueda y sobre esa hace otra búsqueda relacionada. Tarda más pero implementa cierta "inteligencia artificial". El problema es que dependiendo de la búsqueda los resultados pueden ser muy dispares.
# USO MATCH AGAINST
Ahora vamos a ver unas consultas SQL para poder trabajar con MATCH AGAINST. Empezaremos por crear los índices:
- ALTER TABLE `tabla_donde_agregaremos_el_indice` ADD FULLTEXT (`campo`);
- ALTER TABLE `tabla_donde_agregaremos_el_indice` ADD FULLTEXT (`campo1`, `campo2`, `campo3`);
* ¿Y si me equivoco? ¿Puedo eliminar un índice? Claro, pero si tengo multiples índices en el mismo campo, ¿cómo los diferencio? Aquí tienes la solución.
- Primero obtenenemos los índices de la tabla:
SELECT index_name, GROUP_CONCAT(column_name) AS columnas FROM information_Schema.STATISTICS WHERE table_schema = 'base_datos' AND table_name = 'tabla_con_indices' AND index_type = 'FULLTEXT' GROUP BY index_name;
- Una vez que ya sabemos el nombre del índice y las columnas a las que pertenece solamente tenemos que eliminar el que nos interesa:
ALTER TABLE `tabla_donde_agregamos_el_indice` DROP INDEX nombre_del_indice_a_eliminar;
* Podemos usar varias tablas e introducir relaciones en la búsqueda, simplemente agrega JOIN.
* En este ejemplo pasamos directamente al WHERE donde hacemos el mismo MATCH AGAINST para poder filtrar por Relevancia con HAVING. El 1 indica que se encontró una coincidencia, el número cambia según las coincidencias encontradas, en este caso cogemos las que tengan como mínimo 0.5 coincidencias. REduciendo el valor de la relevancia obtenemos más resultados pero estos serán más dispares.
* Ordenamos los resultados según su relevancia de mayor a menor y establecemos un límite de resultados básico de 5 elementos.
Listo, ya puedes comenzar a usar MATCH AGAINST
SELECT `campo1`,`campo2`, MATCH (`campo1`,`campo2`)
AGAINST ('"cadena a buscar*"' IN BOOLEAN MODE) AS Relevancia
FROM `tabla1`
WHERE MATCH (`campo1`,`campo2`)
AGAINST ('"cadena a buscar*"' IN BOOLEAN MODE)
HAVING Relevancia >= 0.5
ORDER BY Relevancia DESC
LIMIT 0 , 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment