[+/-]
MATCH
(
col1
,col2
,...)
AGAINST (expr
[IN BOOLEAN MODE |
WITH QUERY EXPANSION])
MySQL soporta indexación y búsqueda full-text. Un índice
full-text en MySQL es un índice de tipo
FULLTEXT
. Los índices
FULLTEXT
pueden usarse sólo con tablas
MyISAM
; pueden ser creados desde columnas
CHAR
, VARCHAR
, o
TEXT
como parte de un comando
CREATE TABLE
o añadidos posteriormente
usando ALTER TABLE
o CREATE
INDEX
. Para conjuntos de datos grandos, es mucho
más rápido cargar los datos en una tabla que no tenga
índice FULLTEXT
y crear el índice
posteriormente, que cargar los datos en una tabla que tenga un
índice FULLTEXT
existente.
Las restricciones en búsquedas full-text se listan en Sección 12.7.3, “Limitaciones de las búsquedas de texto completo (Full-Text)”.
Las búsquedas full-text se realizan con la función
MATCH()
.
mysql> CREATE TABLE articles ( -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -> title VARCHAR(200), -> body TEXT, -> FULLTEXT (title,body) -> ); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO articles (title,body) VALUES -> ('MySQL Tutorial','DBMS stands for DataBase ...'), -> ('How To Use MySQL Well','After you went through a ...'), -> ('Optimizing MySQL','In this tutorial we will show ...'), -> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), -> ('MySQL vs. YourSQL','In the following database comparison ...'), -> ('MySQL Security','When configured properly, MySQL ...'); Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM articles -> WHERE MATCH (title,body) AGAINST ('database'); +----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 5 | MySQL vs. YourSQL | In the following database comparison ... | | 1 | MySQL Tutorial | DBMS stands for DataBase ... | +----+-------------------+------------------------------------------+ 2 rows in set (0.00 sec)
La función MATCH()
realiza una búsqueda de
lenguaje natural para cadenas contra una colección de textos. Una
colección es un conjunto de una o más columnas incluídas en un
índice FULLTEXT
. La cadena de búsqueda se da
como argumento para AGAINST()
. Para cada
registro en la tabla MATCH()
retorna un valor
de relevancia, esto es, una medida de similaridad entre la cadena
de búsqueda y el texto en el registro en las columnas mencionadas
en la lista MATCH()
.
Por defecto, la búsqueda se realiza de forma insensible a
mayúsculas. Sin embargo, puede realizar búsquedas sensibles a
mayúsculas usando colaciones binarias para columnas indexadas.
Por ejemplo, una columna que usa el conjunto de caracteres
latin1
que puede asignarse una colación de
latin1_bin
para hacerla sensible a mayúsculas
para búsquedas full-text .
Cuando se usa MATCH()
en una cláusula
WHERE
, como en el ejemplo precedente, los
registros retornados se ordenan automáticamente con la relevancia
mayor primero. Los valores relevantes son números en coma
flotante no negativos. Relevancia cero significa que no tiene
similaridad. La relevancia se computa basada en el número de
palabras en el registro, el número de palabras únicas en este
registro, el número total de palabras en la colección, y el
número de documentos (registros) que contienen una palabra
particulas.
Para búsquedas full-text en lenguaje natural, se requiere que las
columnas nombradas en la función MATCH()
sean
las mismas columnas incluídas en algún índice
FULLTEXT
en su tabla. Para la consulta
precedente, tenga en cuenta que las columnas nombradas en la
función MATCH()
(title
y
body
) son las mismas que las nombradas en la
definición del índice FULLTEXT
de la tabla
article
. Si quiere buscar el
title
o body
separadamente,
necesitará crear índices FULLTEXT
para cada
columna.
También es posible realizar una búsqueda boolena o una búsqueda con expansión de consulta. Estos tipos de búsqueda se describen en Sección 12.7.1, “Búsquedas booleanas de texto completo (Full-Text)” y Sección 12.7.2, “Búsquedas de texto completo (Full-Text) con expansión de consulta”.
El ejemplo precedente es una ilustración básica mostrando cómo
usar la función MATCH()
donde los registros se
retornan para decrementar la relevancia. El siguiente ejemplo
muestra cómo recibir los valores de relevancia explícitamente.
Los registros retornados no se ordenan debido a que el comando
SELECT
no incluye cláusulas
WHERE
ni ORDER BY
:
mysql> SELECT id, MATCH (title,body) AGAINST ('Tutorial') -> FROM articles; +----+-----------------------------------------+ | id | MATCH (title,body) AGAINST ('Tutorial') | +----+-----------------------------------------+ | 1 | 0.65545833110809 | | 2 | 0 | | 3 | 0.66266459226608 | | 4 | 0 | | 5 | 0 | | 6 | 0 | +----+-----------------------------------------+ 6 rows in set (0.00 sec)
El siguiente ejemplo es más complejo. La consulta retorna los
valores de relevancia y también ordena los registros en orden
decrecente de relevancia. Para conseguir este resultado, debe
especificar MATCH()
dos veces: una vez en la
lista SELECT
y otra en la cláusula
WHERE
. Esto hace que no haya sobrecarga
adicional, ya que el optimizador de MySQL se da cuenta que hay dos
llamadas MATCH()
son idénticas y invoca la
búsqueda full-text sólo una vez.
mysql> SELECT id, body, MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root') AS score -> FROM articles WHERE MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root'); +----+-------------------------------------+-----------------+ | id | body | score | +----+-------------------------------------+-----------------+ | 4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 | | 6 | When configured properly, MySQL ... | 1.3114095926285 | +----+-------------------------------------+-----------------+ 2 rows in set (0.00 sec)
La implementación MySQL de FULLTEXT
trata
cualquier secuencia de caracteres de palabras (letras, dígitos, y
subrayados) como una palabra. Esa secuencia puede contener
apóstrofes ('
), poro no más que una en un
registro. Esto significa que aaa'bbb
se trata
como una palabra, pero aaa''bbb
se trata como
dos palabras. Los apóstrofoes al principio o fin de una palabra
se eliminan por el parser FULLTEXT
;
'aaa'bbb'
se parsea como
aaa'bbb
.
El parser FULLTEXT
determina dónde empiezan y
acaban las palabras buscando algunos delimitadores, por ejemplo
' '
(el espacio), ,
(coma),
y .
(punto). Si las palabras no se separan por
delmitadores como, por ejemplo, en chino, el parser
FULLTEXT
no puede determinar dónde empieza y
acaba una palabra. Para ser capaz de añadir palabras o índices
indexados en tales idioomas en un índice
FULLTEXT
, debe preprocesarlos para que se
eliminen mediante algún delimitador arbitrario tal como
"
.
Algunas palabras se ignoran en las búsquedas full-text:
Cualquier palabra demasiado corta se ignora. La longitud mínima de las palabras que se encuentran en búsquedas full-text es de cuatro caracteres por defecto.
Las palabras en la lista de palabras de parada se ignoran. Una palabra de parada es una palabra tal como “el” o “algún” que es tan común que se considera que no tiene valor semántico. Hay una lista de palabras de parada, pero puede reescribirse con una lista de palabras definidas por el usuario. Consulte Sección 12.7.4, “Afinar búsquedas de texto completo (Full-Text) con MySQL”.
La longitud de palabra mínima y lista de palabras de parada puede cambiarse como se describe en Sección 12.7.4, “Afinar búsquedas de texto completo (Full-Text) con MySQL”.
Cada palabra correcta en la colección y en la consulta se pesa según su significado en la colección o consulta. Esta forma, una palabra que está presente en varios documentos tiene un peso menor ( y puede incluso tener peso 0), ya que tiene un valor semántico menor en esta colección particular. De modo similar, si la palabra es rara, recibe un peso mayor. Los pesos de las palabras se combinan para computar la relevancia del registro.
Una técnica de este tipo funciona mejor con colecciones grandes
(de hecho, se ajustó con cuidado para funcionar de este modo).
Para tablas muy pequeñas, la distribución de palabras no refleja
automáticamente su valor semántico, y este modelo puede producir
resultados extraños en ocasiones. Por ejemplo, aunque la palabra
“MySQL” está presente en cada registro de la tabla
articles
, una búsqueda de esta palabra no da
resultados.
mysql> SELECT * FROM articles -> WHERE MATCH (title,body) AGAINST ('MySQL'); Empty set (0.00 sec)
El resultado de búsqueda es vacío porque la palabra “MySQL” está presente al menos en el 50% de los registros. Como tal, se trata efectivamente como una palabra de parada. Para conjuntos grandes, este es el comportamiento más deseable--una consulta en lenguaje natural no debe retornar cada segundo registro de una tabla de 1GB. Para conjuntos pequeños, puede ser menos deseable.
Una palabra que coíncide la mitad de registros en una tabla es menos deseable para localizar documentos relevantes. De hecho, es más fácil encontrar muchos documentos irrelevantes. Todos sabemos que esto pasa demasiado frecuentemente cuando tratamos de buscar algo en Internet con un motor de búsqueda. Es con este razonamiento que los registros que contienen la palabra se les asigna un valor semántico bajo para el conjunto particular en que ocurre. Una palabra dada puede exceder el límite del 50% en un conjunto pero no en otro.
El límite de 50% tiene una implicación significante cuando intenta una primera búsqueda full-text para ver cómo funciona: si crea una tabla e inserta sólo uno o dos registros de texto en ella, cada palabra en el texto aparece al menos en el 50% de los registros. Como resultado, no se retorna ningún resultado. Asegúrese de insertar al menos tres registros, y preferiblemente muchos más.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.