En MariaDB, MATCH AGAINST
es una construcción especial utilizada para realizar una búsqueda de texto completo en un índice de texto completo.
Sintaxis
La sintaxis es así:
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
Ejemplo
Supongamos que tenemos una tabla llamada Products
que incluye los siguientes datos:
+----+---------------------------------+-----------------------------------------+ | Id | ProductName | ProductDescription | +----+---------------------------------+-----------------------------------------+ | 1 | Left handed screwdriver | Purple. Includes left handed carry box. | | 2 | Right handed screwdriver | Blue. Includes right handed carry box. | | 3 | Long Weight (blue) | Approximate 45 minute waiting period. | | 4 | Long Weight (green) | Approximate 30 minute waiting period. | | 5 | Sledge Hammer | Wooden handle. Free wine glasses. | | 6 | Chainsaw | Orange. Includes spare fingers. | | 7 | Straw Dog Box | Tied with vines. Very chewable. | | 8 | Bottomless Coffee Mugs (4 Pack) | Brown ceramic with solid handle. | +----+---------------------------------+-----------------------------------------+
Esta tabla tiene un índice de texto completo en su ProductDescription
columna. Eso significa que podemos usar MATCH AGAINST
para hacer una búsqueda de texto completo en esa columna.
Ejemplo:
SELECT
ProductId AS "Id",
ProductName,
ProductDescription
FROM Products
WHERE MATCH(ProductDescription) AGAINST('includes')
ORDER BY ProductId ASC;
Resultado:
+----+--------------------------+-----------------------------------------+ | Id | ProductName | ProductDescription | +----+--------------------------+-----------------------------------------+ | 1 | Left handed screwdriver | Purple. Includes left handed carry box. | | 2 | Right handed screwdriver | Blue. Includes right handed carry box. | | 6 | Chainsaw | Orange. Includes spare fingers. | +----+--------------------------+-----------------------------------------+
Obtener la puntuación
Podemos incluir MATCH AGAINST
en el SELECT
lista para devolver el puntaje de relevancia de la palabra clave dentro de la columna o columnas buscadas:
SELECT
ProductDescription,
MATCH(ProductDescription) AGAINST ('includes') AS Score
FROM Products
WHERE MATCH(ProductDescription) AGAINST ('includes')
ORDER BY Score DESC;
Resultado:
+-----------------------------------------+---------------------+ | ProductDescription | Score | +-----------------------------------------+---------------------+ | Orange. Includes spare fingers. | 0.4883610010147095 | | Blue. Includes right handed carry box. | 0.4883610010147095 | | Purple. Includes left handed carry box. | 0.48305025696754456 | +-----------------------------------------+---------------------+
En este caso también usamos un ORDER BY
cláusula para ordenar por puntaje en orden descendente (es decir, los más relevantes primero).
Columnas sin índice de texto completo
La razón por la que funcionó el ejemplo anterior es porque previamente había creado un índice de texto completo en el ProductDescription
columna. Si no hubiera hecho esto, habría recibido un error.
Esto es lo que sucede cuando intentamos usar MATCH AGAINST
contra una columna que no tiene un índice de texto completo:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
WHERE MATCH(ProductName) AGAINST('screwdriver')
ORDER BY ProductId ASC;
Resultado:
ERROR 1191 (HY000): Can't find FULLTEXT index matching the column list
Agreguemos un índice de texto completo en el ProductName
columna:
ALTER TABLE Products
ADD FULLTEXT(ProductName);
Ahora ejecuta la consulta de nuevo:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
WHERE MATCH(ProductName) AGAINST('screwdriver')
ORDER BY ProductId ASC;
Resultado:
+-----------+--------------------------+--------------+ | ProductId | ProductName | ProductPrice | +-----------+--------------------------+--------------+ | 1 | Left handed screwdriver | 25.99 | | 2 | Right handed screwdriver | 25.99 | +-----------+--------------------------+--------------+
Esta vez funcionó.
Índice de texto completo en varias columnas
Podemos agregar índices de texto completo en varias columnas.
Ejemplo:
ALTER TABLE Products
ADD FULLTEXT(ProductName, ProductDescription);
Ahora podemos ejecutar MATCH AGAINST
contra ese índice de texto completo.
SELECT
ProductId AS Id,
ProductName,
ProductDescription
FROM Products
WHERE MATCH(ProductName, ProductDescription) AGAINST ('weight')
OR MATCH(ProductName, ProductDescription) AGAINST ('ceramic')
ORDER BY Id ASC;
Resultado:
+----+---------------------------------+---------------------------------------+ | Id | ProductName | ProductDescription | +----+---------------------------------+---------------------------------------+ | 3 | Long Weight (blue) | Approximate 45 minute waiting period. | | 4 | Long Weight (green) | Approximate 30 minute waiting period. | | 8 | Bottomless Coffee Mugs (4 Pack) | Brown ceramic with solid handle. | +----+---------------------------------+---------------------------------------+