Categories
Banco de dados Tutoriais

Buscas FULLTEXT requerendo ou excluindo palavras no MySQL

Como realizar buscas FULLTEXT Index no MySQL, usando operadores aritméticos, modo booleano e curingas.

As buscas FULLTEXT Index, no MySQL, são indicadas para encontrar strings (cadeias de caracteres) dentre grandes volumes de texto no banco de dados — por serem extremamente eficientes e entregarem o resultado rápido.
O recurso é flexível o suficiente para permitir que palavras sejam incluídas ou excluídas da busca.
Nos exemplos, que seguem, vou usar a minha tabela ‘biblia’ — justamente por que ela tem um volume de texto consideravelmente grande. Contudo, você pode readequar todos os exemplos aos bancos de dados que tiver disponíveis.
mysql logo over gray ubuntu wallpaper
Se você sentir alguma dificuldade em entender o assunto, sugiro ler o artigo Introdução a buscas FULLTEXT.
Normalmente, as pesquisas FULLTEXT retornam registros que contém uma das palavras incluídas na string de busca, ainda que uma delas não esteja presente no registro.
O exemplo, abaixo, retorna registros que contenham um dos nomes Davi ou Golias:

SELECT COUNT(*) FROM biblia WHERE MATCH(textover) AGAINST('Davi Golias');
+----------+
| COUNT(*) |
+----------+
|      895 |
+----------+
1 row in set (0.00 sec)

No meu banco de dados, há 895 registros contendo ‘Davi’ e/ou ‘Golias’.
Abaixo, segue uma pequena amostra do conteúdo da minha tabela “biblia”, onde é possível ver que nem todos os versículos têm os dois personagens citados simultaneamente em seus textos:

SELECT numliv AS 'Livro',
    -> numcap AS 'Capítulo',
    -> numver AS 'Versículo',
    -> textover AS 'Texto do versículo'
    -> FROM biblia WHERE MATCH(textover)
    -> AGAINST('Davi Golias') LIMIT 5\G;
*************************** 1. row ***************************
              Livro: 9
          Capítulo: 17
         Versículo: 23
Texto do versículo: Enquanto ainda falava com eles, eis que veio subindo do exército dos filisteus o campeão, cujo nome era Golias, o filisteu de Gate, e falou conforme aquelas palavras; e Davi as ouviu.
*************************** 2. row ***************************
              Livro: 9
          Capítulo: 21
         Versículo: 9
Texto do versículo: Respondeu o sacerdote: A espada de Golias, o filisteu, a quem tu feriste no vale de Elá, está aqui envolta num pano, detrás do éfode; se a queres tomar, toma-a, porque não há outra aqui senão ela. E disse Davi: Não há outra igual a essa; dá-ma.
*************************** 3. row ***************************
              Livro: 9
          Capítulo: 22
         Versículo: 10
Texto do versículo: o qual consultou por ele ao Senhor, e lhe deu mantimento, e lhe deu também a espada de Golias, o filisteu.
*************************** 4. row ***************************
              Livro: 9
          Capítulo: 17
         Versículo: 4
Texto do versículo: Então saiu do arraial dos filisteus um campeão, cujo nome era Golias, de Gate, que tinha de altura seis côvados e um palmo.
*************************** 5. row ***************************
              Livro: 13
          Capítulo: 20
         Versículo: 5
Texto do versículo: Tornou a haver guerra com os filisteus; e El-Hanã, filho de Jair, matou Lami, irmão de Golias, o giteu, cuja lança tinha a haste como órgão de tecelão,
5 rows in set (0.01 sec)

Se você deseja ver apenas os resultados em que as duas palavras estejam presentes, o resultado obtido, até agora, é indesejável.
Para obter um resultado mais relevante, reescreva a declaração com o uso do operador AND, para juntar as condições de pesquisa. Veja como:

SELECT numliv AS 'Livro', numcap AS 'Capítulo', numver AS 'Versículo', textover AS 'Texto do versículo' FROM biblia WHERE MATCH(textover) AGAINST ('Davi') AND MATCH(textover) AGAINST ('Golias')\G;

A consulta irá retornar 2 resultados (na minha versão):

*************************** 1. row ***************************
              Livro: 9
          Capítulo: 17
         Versículo: 23
Texto do versículo: Enquanto ainda falava com eles, eis que veio subindo do exército dos filisteus o campeão, cujo nome era Golias, o filisteu de Gate, e falou conforme aquelas palavras; e Davi as ouviu.
*************************** 2. row ***************************
              Livro: 9
          Capítulo: 21
         Versículo: 9
Texto do versículo: Respondeu o sacerdote: A espada de Golias, o filisteu, a quem tu feriste no vale de Elá, está aqui envolta num pano, detrás do éfode; se a queres tomar, toma-a, porque não há outra aqui senão ela. E disse Davi: Não há outra igual a essa; dá-ma.
2 rows in set (0.00 sec)

Use o modo booleano para adicionar termos às suas buscas FULLTEXT no MySQL

O MySQL permite usar o modo booleano para pesquisar a ocorrência de múltiplas palavras. Para fazer uso dele, basta preceder cada palavra com um sinal de adição ‘+’ e acrescentar IN BOOLEAN MODE ao final da string:

SELECT COUNT(*) FROM biblia WHERE MATCH(textover) AGAINST('+Davi +Golias' IN BOOLEAN MODE);
+----------+
| COUNT(*) |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)

O modo booleano também pode ser usado para excluir palavras da busca. Basta usar o sinal de subtração ‘-‘. Veja como:

SELECT COUNT(*) FROM biblia WHERE MATCH(textover) AGAINST('-Davi +Golias' IN BOOLEAN MODE);
+----------+
| COUNT(*) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)

Use o modo booleano do MySQL com curingas

Um outro recurso útil do modo booleano do MySQL é a possibilidade de uso de curingas (wildcards). Ao acrescentar um sinal ‘*’ ao final de uma palavra, você vai obter todos os resultados que a contiverem.
A consulta abaixo, conta todas as ocorrências, na tabela ‘bíblia’ que começam com ‘serv’ — o que inclui servo, serva, servidão, serviço etc:

SELECT COUNT(*) FROM biblia WHERE MATCH(textover) AGAINST('serv*' IN BOOLEAN MODE);
+----------+
| COUNT(*) |
+----------+
|     1435 |
+----------+
1 row in set (0.11 sec)

By Elias Praciano

Autor de tecnologia (livre, de preferência), apaixonado por programação e astronomia.
Fã de séries, como "Rick and Morty" e "BoJack Horseman".
Me siga no Twitter e vamos trocar ideias!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.