MySQL : tri de résultats en fonction du mot-clé

Schwarzer Stern

Membre actif
13 Décembre 2007
249
10
France
www.symphozik.info
Bonsoir à tous,

J'ai une question pour les spécialistes de MySQL. Je développe en ce moment un moteur de recherche en PHP à usage personnel mais je bute sur un problème, à savoir le tri des résultats par pertinence (plutôt que par ordre alphabétique ou autre).
Exemple simplifié avec la table suivante :
personne(Num,Nom,Prenom,Commentaire);

Contenant deux entrées :
1,"DURAND","Pascal"
2,"PASQUIER","Jérôme"

Si je recherche "PAS", c'est l'entrée 1 qui va s'afficher en premier, alors que je souhaiterai donner la priorité à la 2 vu que le nom est plus important (dans ce cas).

J'ai trouvé des éléments de réponse en créant un index sur Nom et Prenom puis en ajoutant "match (Nom,Prenom) against ('pas') as compteur" et "order by compteur" mais la valeur de CPT reste à 0. Je me tourne donc vers vous pour m'aider :)

J'espère avoir été clair, merci d'avance en tout cas
 
T'as juste à définir une fonction qui renvoie un indice de pertinence sur le résultat, et à l'appeler dans le orderby, genre select * from x where .. order by maFonction(nom,prenom)

(après selon la dite fonction et le nombre de lignes, à toi de voir ce que ça donne sur les perfs)
 
Sinon MySQL a un truc super pour ce genre de problème : match against.

Faut voire dans la doc je sais pas ça par coeur, mais y a une histoire de faire deux requêtes imbriquées dont une (ou les deux ?) à base de math against et hop les résultats sont là à la bien dans le bon ordre. En plus y a des features cool genre ça ignore les mot de la recherche si ils sont dans trop d'entrée de la table par exemple.
:)
 
Bon, il y a du mieux avec "match against"...mais ce n'est pas encore ça :
J'ai écris la requête suivante :
SELECT *, MATCH (NomComp, Biographie) AGAINST ('mozart') AS score FROM compositeur where MATCH (NomComp, Biographie) AGAINST ('mozart') order by score desc

Mais 1/, il devrait renvoyer à peu près les mêmes résultats pour "mozar", mais il n'en n'est rien, et ce pour tous les tests quelle que soit la longueur du nom (je précise qu'il s'agit d'un moteur dont la recherche est sensée être simultanée à la frappe). De plus, la pertinence laisse à désirer; pour "mozart", j'aimerai au moins que le père et le fils réalisent les scores les plus élevés, là je n'ai que le père. Pourtant, la bio du fils contient plus de 40 fois "Mozart", et celle du père moins de 5 fois...

le moteur est à tester ici : http://www.symphozik.info/Recherche-beta.html
Il affiche la requête si jamais vous voulez la vérifier en vrai.



Si vous pouvez me tirer de là, merci bien :)
 
Ce qui est étrange c'est que Mozart (Wolfgang) n'apparaît jamais, quelle que soit la recherche que l'on tape... Ça vient peut-être de tes données ?

Soit dit en passant je modifierais ta requête ainsi :
Bloc de code:
SELECT *, MATCH (NomComp, Biographie) AGAINST ('mozart') AS score FROM compositeur where score > 0 ORDER BY score DESC

De même essaye de spécifier les champs que tu souhaites obtenir, d'autant plus si tu effectues ta requête dynamiquement, de façon à alléger les communications avec le serveur ;)
 
Au temps pour moi, ça faisait un moment que j'avais pas utilisé cette fonction ^^

De ce que je vois sur la doc, la fonction calcule la pertinence de ton résultat, et la principale différence que je vois entre le père et le fils, c'est que le nom est en premier pour le père, et en second pour le fils. Essaye d'inverser cet ordre pour le fils, et à priori il reviendra à la place qui est sienne.

Je pense que pour des petits textes (comme c'est le cas pour les noms), la pertinence sera le nombre d'occurences coefficienté par l'inverse de la position du mot. Mais j'en suis pas certain, en tout cas tu peux toujours essayer :)
 
Arf au temps pour moi j'ai encore confondu, les noms ne sont pas les mêmes lorsque l'on va sur la biographie que lorsqu'on voit les résultats...

Bon, d'après la doc :
La pertinence est calculé en fonction du nombre de mots dans la ligne, du nombre de mots uniques dans cette ligne, du nombre total de mots dans la liste, et du nombre de documents (lignes) qui contiennent un mot en particulier.

Je sais pas trop quelle peut être la différence entre le nombre de mots/total/uniques, mais tu peux regarder dans cette direction.
 
Bon, j'ai préféré bidouiller un peu quitte à peut-être perdre en performances (mais je n'ai pas une BDD de taille industrielle donc bon ^^)
J'ai ajouté un code php qui vérifie si le terme recherché est contenu dans "NomComp", et si c'est le cas il déplace la ligne en haut de liste.
ça vaut ce que ça vaut hein :X

merci du temps passé