Recherche SQL par mot clés
Posté : 09 févr. 2009, 12:06
Pour le besoin d'un site de questions réponses, je dois effectuer une recherche de question équivalante à une question donnée. Pour ceci, je pense que le mieux est une recherche par mot-clé.
Une question se définit comme ceci : un intitulé, et une question. L'intutilé est la question avec juste quelques mots.
Par exemple :
Intitulé : Linux ou windows
Question : Parmis le vaste choix que nous offre les differents développeurs, quel est le meilleur OS adapté à mon systeme ? Windows XP, Vista ? une distribution Linux (red hat ou debian ?) ? un Mac OS ? un openBSD pour une meilleure sécurité ? ou même pourquoi pas un systême Unix ?
(ps : c est un exemple, pas de troll
)
Je prends l intitulé de la question auquel j enleve les mots de moins de 3 lettres par une simple fonction puis je fais ma recherche. Mais le probleme est là : comment je fais ma requete SQL, sans qu'elle ne soit trop lourde aussi.
J avais pensé au MATCH...AGAINST mais ça ne resout pas mon soucis.
Je suis sur MySQL, voila le code de la table question. J ai rajouté un champ tag_question, qui peut contenir differents tags
Les deux methodes qui nous interesse de ma classe :
Et voila ce que ça me retourne :
EDIT
J ai trouvé comment faire. Voila la fonction :
Une question se définit comme ceci : un intitulé, et une question. L'intutilé est la question avec juste quelques mots.
Par exemple :
Intitulé : Linux ou windows
Question : Parmis le vaste choix que nous offre les differents développeurs, quel est le meilleur OS adapté à mon systeme ? Windows XP, Vista ? une distribution Linux (red hat ou debian ?) ? un Mac OS ? un openBSD pour une meilleure sécurité ? ou même pourquoi pas un systême Unix ?
(ps : c est un exemple, pas de troll
Je prends l intitulé de la question auquel j enleve les mots de moins de 3 lettres par une simple fonction puis je fais ma recherche. Mais le probleme est là : comment je fais ma requete SQL, sans qu'elle ne soit trop lourde aussi.
J avais pensé au MATCH...AGAINST mais ça ne resout pas mon soucis.
Je suis sur MySQL, voila le code de la table question. J ai rajouté un champ tag_question, qui peut contenir differents tags
Code : Tout sélectionner
CREATE TABLE IF NOT EXISTS `question` (
`id_question` int(10) unsigned NOT NULL auto_increment,
`id_categorie` int(10) unsigned default NULL,
`pseudo` text,
`intitule_question` text,
`tag_question` text NOT NULL,
`question` text,
`date_question` text,
PRIMARY KEY (`id_question`),
UNIQUE KEY `intitule_question` (`intitule_question`(4))
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
function sup_3($var){
$tab = explode(' ', $var); //on explose la chaine de caractere pour avoir un tableau
for($i=0 AND $var=NULL; count($tab[$i]); $i++) { //parcours du tableau
if(strlen($tab[$i])>3){ //Si la longueur d un element d un tableau est superieur à 3, on rajoute un espace
$str .= '\''.$tab[$i].'\',';
}//fin if
}//fin for
$str = substr($str,0,strlen($str)-1); //enleve la derniere virgule
//$str = str_replace('-.','',$str);
return $str;
}
function _rechercheQuest($chaine){
$this->m_nAccesBD->connexion(); //Connexion BD
$chaine = mysql_real_escape_string($chaine);
$sRequete = 'SELECT * FROM question WHERE id_question <> '.$this->id_question;
$sRequete .= ' AND MATCH (intitule_question) AGAINST ('.$chaine.')';
$sRequete .= ' ORDER BY rand() LIMIT 0,10';
$rResultat = $this->m_nAccesBD->requete($sRequete);
$this->m_nAccesBD->deconnexion(); //Deconnexion
//Traitement de l affichage de la requete SQL a venir
}
et voila comment j affiche :
//creation de l objet etc...
echo 'Recherche sur les termes suivants : <em>';
//Si le champ TAG n est pas vide, on fait la recherche direct
if(!empty($oQuestion->m_aAffichQuestion['tag_question'])){
$aCleRech_Q = strtolower(stripslashes($oQuestion->m_aAffichQuestion['tag_question']));
echo $oQuestion->sup_3($aCleRech_Q).'</em>';
$oQuestion->_listeQuestionProche = $oQuestion->_rechercheQuest($oQuestion->sup_3($aCleRech_Q));
}else{
//Sinon, on prend le champs intitule_question, on lui enleve les mots de moins de 3 lettre et on fait la recherche
$aCleRech_Q = strtolower(stripslashes($oQuestion->m_aAffichQuestion['intitule_question']));
echo $oQuestion->sup_3($aCleRech_Q).'</em>';
$oQuestion->_listeQuestionProche = $oQuestion->_rechercheQuest($oQuestion->sup_3($aCleRech_Q));
}
Je ne fais pas encore d affichage de la requete SQLEt voila ce que ça me retourne :
Merci d'avance ^^Recherche sur les termes suivants : 'linux', 'windows'
Une exception a été gérée :
Message : Probleme d execution de requete SQL : SELECT * FROM question WHERE id_question <> 3 AND MATCH (intitule_question) AGAINST ('linux', 'windows') ORDER BY rand() LIMIT 0,10
Message : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' 'windows') ORDER BY rand() LIMIT 0,10' at line 1
A la ligne : 40
EDIT
J ai trouvé comment faire. Voila la fonction :
function _rechercheQuest($chaine){
$chaine = explode(",",$chaine);
$this->m_nAccesBD->connexion(); //Connexion BD
$sRequete = 'SELECT *, MATCH(`intitule_question`) AGAINST('.$chaine[0].') AS score FROM question';
$sRequete .= ' WHERE id_question != '.$this->id_question.' AND ' ;
$sRequete .= 'MATCH (`intitule_question`) AGAINST ('.$chaine[0].')';
for($i = 1;$i<count($chaine);$i++){
$sRequete .= ' OR MATCH (`intitule_question`) AGAINST ('.$chaine[$i].')';
}
//echo '<p>Requete SQL : '.$sRequete.'</p>';
$rResultat = $this->m_nAccesBD->requete($sRequete);
$this->m_nAccesBD->deconnexion(); //Deconnexion
$aQuestProche = array();
while($aListe = mysql_fetch_array($rResultat)){
$aQuestProche[$aListe['id_question']] = $aListe;
}
return $aQuestProche;
}