Module de recherche

Eléphant du PHP | 186 Messages

07 nov. 2007, 11:38

Bonjour à tous!

J'essaie de mettre en place un petit module de recherche interne à mon site et comme je ne trouve pas mon bonheur sur des scripts tout fait, j'ai décidé de le faire moi même afin qu'il corresponde à mes exigences.

Mais la tâche s'avère rude et longue. C'est pourquoi je viens demander un peu d'aide.

Pour info, je souhaite questionner ma base de données en fonction d'une requête d'environ 3 mots et faire ressortir les enregistrements correspondants.
Jusque là pas trop de problème même si je pense que mon code n'est pas très optimisé mais je m'en inquieterai plus tard.

J'arrive donc à afficher les résultats mais comme certains sont plus pertinents par rapport à la recherche effectuée, j'aimerai les afficher en premier.

La recherche porte actuellement sur un seul champ d'une table de ma bd. Ainsi, si la recherche est composée de 3 mots et qu'ils sont retrouvés dans un des résultats, je voudrais que ces derniers soient affichés en premier, puis on retrouverait ceux qui correspondent à 2 mots de la recherche et enfin ceux où l'on ne retrouve qu'un seul mot.

Pour le moment, j'affiche mes résultats dans une boucle dont l'ordre n'est pas défini. J'arrive aussi à déterminer la pertinence de chaque résultat par rapport à la recherche effectuée en calculant le nombre de mots retrouvés.
Maintenant, il faudrait que j'arrive à classer les résultats par pertinence en fonction du nombre de mots retrouvés. Mais là, c'est le trou noir. Je ne vois pas trop comment faire puisqu'en fait, pour calculer cette pertinence, il faut déjà que la requête générant les résultats soit effectuée ce qui fait que je ne peux pas mettre de ORDER BY dessus.

Voici mon code:
//Requête renvoyant les résultats liés à la recherche
$query_rs_resultat2="SELECT DISTINCT nom_etab FROM tbl_etab, tbl_etab_type WHERE tbl_etab.type_etab=tbl_etab_type.etab_type AND (nom_etab LIKE '%".$mot."%'".$premiermot.$deuxiememot.$troisiememot.")";
$rs_resultat2 = mysql_query($query_rs_resultat2, $conn_develop) or die(mysql_error());

//Boucle affichant les résultats
while ($row_rs_resultat2 = mysql_fetch_assoc($rs_resultat2)) {

//Vérification de la présence des mots recherchés dans les résultats de la requête
$test1 = strstr(str_replace(" ",",",strtolower($row_rs_resultat2['nom_etab'])), $premiermot);
$test2 = strstr(str_replace(" ",",",strtolower($row_rs_resultat2['nom_etab'])), $deuxiememot);
$test3 = strstr(str_replace(" ",",",strtolower($row_rs_resultat2['nom_etab'])), $troisiememot);

if(($test1!='') && ($test2!='') && ($test3!='')) {
	$ordre1b = 1;
} else {
	$ordre1b = 0;
}
if((($test1!='') && ($test2!='')) || (($test1!='') && ($test3!='')) || (($test2!='') && ($test3!=''))) {
	$ordre2b = 1;
} else {
	$ordre2b = 0;
}
if(($test1!='') || ($test2!='') || ($test3!='')) {
	$ordre3b = 1;
} else {
	$ordre3b = 0;
}
$ordre2 = $ordre1b+$ordre2b+$ordre3b;
echo
// J'affiche les noms correspondant à la recherche et le degré de pertinence
$row_rs_resultat2['nom_etab'].' '
.$ordre2.' <br/>
';}
Merci pour toute aide et conseil que vous pourrez m'apporter.

ViPHP
ViPHP | 5924 Messages

07 nov. 2007, 14:16

Est ce que tu peux poster le schéma de tes tables sous la forme CREATE TABLE (fonction exporter sous phpmyadmin) ?

ViPHP
ViPHP | 4039 Messages

07 nov. 2007, 15:29

En passant, MySQL offre déjà pas mal de fonctionnalités, avec des recherches booléennes et tout le toutim.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Eléphant du PHP | 186 Messages

07 nov. 2007, 15:32

Ma table tbl_etab est celle qui récupère toutes les infos communes à tous les enregistrements de ma bd.
Mon site repertorie des annonceurs et le schema de ma table est de type
id_etab INT clé primaire
nom_etab VARCHAR (nom de l'annonceur sur lequel la recherche va porter)
type_etab VARCHAR (me sert à faire la jointure avec l'autre table afin d'établir plus tard le lien vers la page de l'annonceur)

Mon autre table tbl_etab_type me sert à repertorier les types d'annonceur
id_etab_type INT clé primaire
etab_type VARCHAR (nom du type d'annonceur ex:hotel)
url_page VARCHAR (ex: http://www.site.fr/pageannonceur.php)

Je ne sais pas si je t'ai fourni les infos comme tu le souhaitais mais voila les champs qui vont m'être utile pour ce que je veux.

Je viens d'essayer d'utiliser la méthode en full text avec MATCH mais le message suivant apparait:
The used table type doesn't support FULLTEXT indexes.
Mon site est hebergé sur un serveur mutualisé donc ma marge de manoeuvre est limitée.

Eléphant du PHP | 186 Messages

07 nov. 2007, 17:53

J'ai lu qu'il fallait que ma table ait un index en fulltext pour pouvoir utiliser la recherche avec MATCH(...) AGAINST(...) et que ma table soit en MyISAM.
Les index FULLTEXT sont utilisés avec les tables MyISAM et peuvent être créés depuis des colonnes de types CHAR , VARCHAR , ou TEXT au moment de CREATE TABLE ou plus tard avec ALTER TABLE ou CREATE INDEX
Comment faut-il proceder avec un alter table pour rajouter l'index.

J'ai la synthaxe avec le create table:

Code : Tout sélectionner

mysql> CREATE TABLE articles ( -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -> title VARCHAR(200), -> body TEXT, -> FULLTEXT (title,body) -> );
mais comme ma table existe déjà du coup je vois pas trop comment faire!!

Rajouter un index full text a-t'il une incidence sur le reste du fonctionnement de la base?
La recherche en full text est-elle mieux que la méthode que j'utilise avec LIKE, hormis le fait que je n'arrive pas avec LIKE à ordonner mes résultats par pertinence?

Merci pour vos conseils.

ViPHP
ViPHP | 5924 Messages

07 nov. 2007, 20:00

Comment faut-il proceder avec un alter table pour rajouter l'index.
Normalement :

Code : Tout sélectionner

ALTER TABLE articles ADD INDEX FULLTEXT(title,body);
Rajouter un index full text a-t'il une incidence sur le reste du fonctionnement de la base?
La table prendra plus de place, mais les recherches et tris sur les champs en FULLTEXT seront accélérés.
La recherche en full text est-elle mieux que la méthode que j'utilise avec LIKE, hormis le fait que je n'arrive pas avec LIKE à ordonner mes résultats par pertinence?
A partir d'une certaine quantité de données oui, assurément.

Eléphant du PHP | 186 Messages

08 nov. 2007, 10:30

Merci Sékiltoyai pour tes réponses.
J'ai réussi à mettre l'index sur mon champ.
Par contre au niveau de la recherche en full text, comment sont traités les mots composant la recherche?
I.E. si je tape "agence immobilier", la recherche porte sur le couple de mots ou sur chaque mot?
En tout cas, si je tape juste "immobilier" le résultat occulte les résultats avec le mot immobiliere, y a t'il un moyen pour que ca les prenne en compte?

ViPHP
ViPHP | 4039 Messages

08 nov. 2007, 10:42

As-tu une connaissance des moteurs de recherche classiques (avec tout ce qui va avec; boolean search, fuzzy, stemming, etc..) ?
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Eléphant du PHP | 186 Messages

08 nov. 2007, 11:08

C'est la première fois que je met en place un moteur de recherche interne, donc non, je n'ai pas de connaissances précises sur le sujet.
Par contre je sais que le boolean mode ne conviendra pas à ce que je veux faire. Je vais prendre connaissance des autres que tu cites.

ViPHP
ViPHP | 4039 Messages

09 nov. 2007, 11:55

boh, ce ne sont que des paramètres de recherche. (fuzzy (recherche floue) permet de faire des recherches malgré des erreurs de frappe, et stemming fait varier grammaticalement les mots, pour rendre la recherche plus pertinente)
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Eléphant du PHP | 186 Messages

09 nov. 2007, 18:11

Bonjour!
Bon à présent j'arrive à peu près à faire fonctionner mon module de recherche comme je le souhaite.
Dernière ombre noire à mon tableau, la présence de guillemets ou de quote dans la recherche tapée mais aussi dans les données stockées dans ma bd.
Pour le moment, lorsqu'un guillemet ou une quote est tapé dans la recherche, je les remplace par un espace.
Le probleme c'est que la recherche ne me trouve plus les résultats comportant des guillemets ou des apostrophes.
Par exemple si la personne qui effectue une recherche tape: l'iguane, la recherche va porter sur l iguane et donc ne vas pas trouver le résultat portant comme non l'iguane.
De même pour les résultats mis entre guillemets.
Vous aller me dire, alors pourquoi remplacer les guillemets et apostrophes par des espaces? C'est juste que lorsque j'effectue certaine de mes requêtes la présence de ces caractères spéciaux me pose de sérieux problèmes comme vous le savez sans doute.
Existe-t'il un moyen pour que la présence de guillemets ou d'apostrophes que ce soit dans la recherche tapée ou dans les noms présents dans ma bd ne me pose pas de problème?
merci pour vos réponses.

ViPHP
ViPHP | 5924 Messages

10 nov. 2007, 14:24

mysql_real_escape_string()

Eléphant du PHP | 186 Messages

15 nov. 2007, 10:57

Merci pour tous ces renseignements. Ils m'ont été très utiles.
J'arrive à un résultat qui me satisfait largement.
Bonne continuation à tout le monde.