Scripter un moteur de recherche nécessite :
- un formulaire côté client pour soumettre des requêtes
- des champs de table de base de données à l’intérieur desquels la recherche doit s’effectuer
- des requêtes à la base de données pour rechercher la chaîne postée par le client
Je veux tout d’abord me pencher sur les caractéristiques de la base de données pour effectuer une telle recherche.
Auaparavant, j’utilisais des requêtes avec des sous-requêtes du type :
SELECT id,title,content from table_name WHERE title LIKE ‘%”.$search.”%’ OR content LIKE ‘%”.$search.”%’;
qui effectue une recherche de style expression régulière et peut causer des problèmes de ressources MySql (grand nombre de lignes parcourues, grand nombre de résultats,…).
Sous MySql, une recherche FULLTEXT peut solutionner ce problème de ressources et produire des résultats probants puisqu’elle effectue une recherche sur des données indexées, et donc pas directement dans la table. Ce type de recherche permet l’utilisation :
- d’une liste de mots rejetés (mots que le serveurs exclut par défaut de la recherche)
- de recherches booléennes (utilisant + ou -, par exemple, pour ajouter ou enlever des mots de la recherche)
- d’un score de pertinence
Type de table qui permet l’indexation Fulltext
La recherche FULLTEXT est disponible avec les tables utilisant MyISAM comme moteur de stockage. Bien que le moteur de stockage InnoDB offre l’énorme avantage de pouvoir utiliser des transactions (gestion des erreurs par commit et rollback), la recherche par indexation Fulltext y est absente. Concentrons-nous donc sur les tables MyISAM.
Vous pouvez définir un index Fulltext sur un ou plusieurs champs de type CHAR, VARCHAR et TEXT. Comme mentionné dans la référence MySql reference sur le sujet, créer des données dans une table disposant d’un index Fulltext prendra plus de temps. Ainsi, si un nombre conséquent de données doit être traité avec un index Fulltext (et c’est dans ce cas qu’il sera le plus efficace), il vaut mieux d’abord insérer les données dans la table, puis créer l’index.
Vous pouvez créer un index sur les 2 champs “title” et “content” avec la requête suivante :
ALTER TABLE table_name ADD FULLTEXT index_name (‘title’ , ‘content’);
Une fois l’index Fulltext de la table défini, faites une recherche comme suit :
SELECT id,title,content from table_name WHERE MATCH(title,content) AGAINST (‘”.$search.”‘);
Les champs de la sous-requête MATCH doivent être les mêmes que ceux définis dans l’index fulltext de la table, et vous pouvez créer un index Fulltext sur un champ ou plus.
Paramétrage de la recherche Fulltext
MySql est configuré avec un lot de paramètres par défaut :
- les résultats sont classés par score de pertinence que MySql donne à chaque donnée trouvée
- les mots de moins de 4 caractères seront ignorés
- l’index Fulltext contient uniquement des mots entiers
- liste des mots exclus d’une recherche Fulltext. Ce paramètre dépend de la langue d’installation de MySql
- le score de chaque donnée trouvée dépendra du nombre d’occurences de ce mot dans la table. Si un mot apparaît dans plus de la moitié des lignes de la table, il sera ignoré
Le changement de ces paramètres par défaut ne sera possible que dans le cas où votre serveur Web MySql vous permet de les modifier.
Recherche en mode booléen
La sous-requête MATCH… AGAINST… permet la recherche booléenne :
SELECT id,title,content from table_name WHERE MATCH(title,content) AGAINST (‘”.$search.”‘ IN BOOLEAN MODE);
MySql retournera toutes les lignes correspondantes même si plus de 50% des lignes contiennent le mot-clef.
Les recherches booléennes permettent en outre l’utilisation d’opérateurs comme + ou – pour forcer MySql à retourner les lignes contenant ‘works’ et cacher les lignes contenant ‘tables’ :
SELECT id,title,content from table_name WHERE MATCH(title,content) AGAINST (‘+works -tables’ IN BOOLEAN MODE);
Vous pouvez aussi utiliser l’opérateur * comme joker en mode booléen pour rechercher une partie de mot :
SELECT id,title,content from table_name WHERE MATCH(title,content) AGAINST (‘peopl*’ IN BOOLEAN MODE);
Référence sur la recherche FULLTEXT sous MySql
Référence sur la recherche FULLTEXT en mode Booléen sous MySql