Przeglądając kody źródłowe różnych “wyszukiwarek” podpiętych do różnych serwisów, nigdy nie mogę się nadziwić - czego to ludzie nie wymyślą. MySQL jako baza danych wspiera od pewnego czasu przeszukiwanie tekstu zarówno poprzez wyrażenia regularne jak i Full-Text search. Tak więc nie radzę trudzić się i pisać różne dziwne przeszukiwania na poziomie php jeżeli mamy odpowiedni zestaw funkcji po stronie bazy danych.
Na początek załóżmy testową tabelę:
CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) );
Następnie wypełnijmy ją danymi:
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 ...');
spróbujmy znaleźć wszystkie rekordy które w tytule i treści mają wpisane słowo “database”:
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');
Proste i przy okazji pozbyliśmy się słówka “OR” z zapytania.
Możemy także sprawdzić jak bardzo dany wynik pasuje do naszego wyszukiwania np:
SELECT id, MATCH (title,body) AGAINST ('Tutorial') FROM articles;
Zwróci nam nie tylko id artykułu ale i stopień w jakim tytuł i treść pasują do wyszukiwania słowa “Tutorial”.
Dodatkowo można sobie zażyczyć aby podczas wyszukiwania można było określać które słowa nie powinny wystąpić w wynikach np:
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
Czyli szukamy wszystkie artykuły ze słowem MySQL ale bez słowa YourSQL.
Jak widać ten typ zapytań upraszcza życie i odciąża bazę w porównaniu z zapytaniami opartymi na OR’ach. Dla ciekawych możliwości polecam dokumentację MySQL‘a a w szczególności:
fulltext natural language
fulltext boolean