jeudi 17 Avr 2008

Concevoir un moteur de recherche intelligent

PHPQuand on développe un site comportant plein de pages basées sur le même modèle (blog, boutique, forum, annuaire...) on a toujours besoin d'un moteur de recherche qui va aller interroger la base de données.

Là les choses se compliquent, puisque en cherchant "vidéos" on ne trouvera pas les article comportant le mot "video" alors qu'il le faudrait. :-(

Heureusement, il y a une solution c'est utiliser un soundex ou phonex. C'est un algorithme qui se basera sur la phonétique des mots pour proposer des réponses proches du terme cherché.


Après quelques recherches, j'ai trouvé que MySQL propose un soundex intégré, malheureusement plutôt adapté à l'anglais. De plus, le mot cherché n'est pas forcément stocké tout seul dans un champ de la base. S'il fait partie d'un texte plus long, ça ne fonctionne plus.

'recherche' est mon mot à chercher:
SELECT * FROM articles WHERE SOUNDEX(titre) = SOUNDEX('recherche')
équivalent à:
SELECT * FROM articles WHERE titre SOUNDS LIKE 'recherche'

On peut également faire des index "texte entier" dans MySQL, ce qui permet de chercher un mot dans un plus grand texte avec MATCH:

SELECT * FROM articles WHERE MATCH titre AGAINST ('recherche')

Mais là on a le mot exact et plus les mots ressemblant. L'idéal serait de pouvoir mélanger les 2 choses pour chercher UN mot dans la base RESSEMBLANT au terme cherché.

Mais ça n'existe pas (encore)... :-|

(Désolé, je ne connait pas vraiment d'autres bases de données que MySQL, bien que je préfèrerais utiliser plutôt PostGreSQL.)


Ma solution: créer une table dictionnaire dans la base qui contient les soundex de tous les mots du site, avec une référence à l'article où on peut les trouver.

En cherchant le soundex de "vidéos" dans ma table dictionnaire, je vais trouver les références aux articles contenant "video" et je n'ai plus qu'à afficher les résultats.

Avec une petite réserve: les mots retournés sont parfois très éloignés du mot cherché, bien qu'ils aient la même phonétique. J'applique donc la fonction levenshtein avant d'afficher un résultat, s'il est trop éloigné, je le jette.


La partie difficile se trouve plutôt lors de l'enregistrement des articles. Vous devez rajouter une fonction qui se chargera de:

  1. effacer les références à l'article s'il existait déjà (modification)
  2. découper les articles mot par mot (en éliminant les mots <3)
  3. calculer le soundex de ces mots
  4. vérifier s'ils sont déjà dans la base, dans ce cas rajouter la référence de l'article,
  5. sinon ajouter un nouveau "son" dans le dictionnaire, avec la référence de l'article.

Pour cela vous avez donc besoin d'une fonction qui crée le "son" approximatif d'un mot. C'est en cherchant cela que je suis tombé sur l'excellent article pour créer un soundex francophone sur le blog Mind.

Sur sa page, vous y trouverez le code de la fonction soundex en PHP qu'il a créée et où j'ai apporté ma contribution ;-) suivant les commentaires des lecteurs et mes propres observations.

Vous pourrez même tester en bas de page le résultat obtenu pour un mot. Vous verrez que des mots similaires donne le même "son", c'est ce que nous voulions, mais qu'un affinage avec levenshtein est indispensable.


Maintenant ce soundex fonctionne bien et je l'ai utilisé sur un site. Il sera mis en place sur la boutique d'un client. Il n'est pas encore en ligne et je n'ai pas à leur faire de la pub donc je ne met pas de lien. :-p


café Cet article vous a aidé? 
Offrez-moi un café!
Agrégateur informatique

3 réponses à “Concevoir un moteur de recherche intelligent”

  1. 1
    ced a dit:

    Bonjour,
    J'ai vraiment besoin d'aide
    Je cherche comment je pourrai faire un moteur qui permettrai aux internautes de faire une requête sur mon site.( et que sur mon site)
    Je m'explique par un exemple qui je l'espère sera simple et clair:
    La personne sélectionne dans un menu déroulant " Voiture"
    dans un second menu il sélectionne " Française"
    ensuite dans un troisième il sélectionne " rouge"
    et enfin un code postal dans le dernier champ

    Et moi je souhaite que ce moteur fasse: " voiture+française+rouge+code postal" = une page html précise.
    pour info j'utilise Nvu ..
    Un grand Merci pour votre aide.

  2. 2
    David (azur-dev.kizone.net) a dit:

    Il faut passer par du PHP pour traiter le formulaire. C'est tout simple, mais il faut bien sûr avoir les bases. ;-)

    Je peux vous le faire, mais je ne travaille pas bénévolement. :-p

  3. 3
    Hugo Vacher a dit:

    Bonjour,

    Merci beaucoup pour ton article, je viens d'apprendre deux nouveaux concepts grâce à toi, mais je trouve ça encore vraiement lourd pour de la simple recherche.

    Si non si nous utilisons cette solution, je pense qu'utiliser des TRIGGER serais une bonne option pour la table de mots clefs.

    Merci encore

Laisser un commentaire

Azur Dev