Comment modiifier ce code pour avoir une recherche multiple?

Comment modiifier ce code pour avoir une recherche multiple? - PHP - Programmation

Marsh Posté le 24-03-2009 à 20:46:33    

Bonjour,
 
J'ai un soucis, mon moteur de recherche ne trouve que des expressions exactes. Par exemple si un utilisateur à posté une annonce comme ceci:
"petite voiture verte diesel"
 
Si j'entre "petite voiture" dans mon moteur, c'est bon il trouve l'annonce. Par contre si j'entre "petite verte", il ne me trouve rien.
 
Savez-vous comment je pourrais modifier ce code pour que mon moteur trouve l'annonce en tapant deux mots contenus dans l'annonce mais qui ne se suivent pas forcément?
 

Code :
  1. if ($text_search <> "" ) {
  2.  $search .= " AND (a.ad_headline LIKE '%$text_search%' OR a.ad_text LIKE '%$text_search%') AND a.published = 1";
  3. }
  4. else
  5.  $search .= " AND a.published = 1";


Message édité par hazmoon le 26-03-2009 à 15:18:28
Reply

Marsh Posté le 24-03-2009 à 20:46:33   

Reply

Marsh Posté le 25-03-2009 à 08:20:12    

Tu peux peut-être essayer de découper $text_search selon les espaces pour gérer cela :
 
Par exemple :

Code :
  1. if ($text_search <> "" ) {
  2. $tabTxt = preg_split("/[\s]+/", $text_search);
  3. $headline = "" ;
  4. $text = "" ;
  5. foreach($tabTxt as $txt) {
  6.  if(trim($txt) === "" ) {
  7.   continue ;
  8.  }
  9.  $headline .= "a.ad_headline LIKE '%$txt%' AND" ;
  10.  $text .= "a.ad_text LIKE '%$txt%' AND" ;
  11. }
  12. $headline = substr($headline, 0, -3) ;
  13. $text = substr($text, 0, -3) ;
  14. $search .= " AND ( ($headline) OR ($text)) AND a.published = 1";
  15. }
  16. else
  17.     $search .= " AND a.published = 1";

Cela va donner une requête du genre :
 
" AND ( (a.ad_headline LIKE '%petite%' AND a.ad_headline LIKE '%verte%' ) OR (a.ad_text LIKE '%petite%' AND a.ad_text LIKE '%verte%' )) AND a.published = 1"
 
Donc l'ordre des mots ne sera plus importants...


---------------
Tous les programmeurs sont des auteurs et tous les ordinateurs sont de mauvais acteurs.
Reply

Marsh Posté le 25-03-2009 à 09:35:08    

encore toi? T'as déjà ouvert un topic sur le même sujet avec le même bout de code...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 25-03-2009 à 11:10:06    

rufo a écrit :

encore toi? T'as déjà ouvert un topic sur le même sujet avec le même bout de code...

 

Oui je m'excuse! Mais je voulais vraiment trouver une solution! J'étais un peu coincer! Mais ça a porté ces fruits, puisque j'ai maintenant la solution!

 

Merci de votre compréhension!


Message édité par hazmoon le 25-03-2009 à 11:10:30
Reply

Marsh Posté le 25-03-2009 à 11:13:33    

DaSayan a écrit :

Tu peux peut-être essayer de découper $text_search selon les espaces pour gérer cela :

 

Par exemple :

Code :
  1. if ($text_search <> "" ) {
  2. $tabTxt = preg_split("/[\s]+/", $text_search);
  3. $headline = "" ;
  4. $text = "" ;
  5. foreach($tabTxt as $txt) {
  6.  if(trim($txt) === "" ) {
  7.   continue ;
  8.  }
  9.  $headline .= "a.ad_headline LIKE '%$txt%' AND" ;
  10.  $text .= "a.ad_text LIKE '%$txt%' AND" ;
  11. }
  12. $headline = substr($headline, 0, -3) ;
  13. $text = substr($text, 0, -3) ;
  14. $search .= " AND ( ($headline) OR ($text)) AND a.published = 1";
  15. }
  16. else
  17.     $search .= " AND a.published = 1";

Cela va donner une requête du genre :

 

" AND ( (a.ad_headline LIKE '%petite%' AND a.ad_headline LIKE '%verte%' ) OR (a.ad_text LIKE '%petite%' AND a.ad_text LIKE '%verte%' )) AND a.published = 1"

 

Donc l'ordre des mots ne sera plus importants...

 

Merci beaucoup pour ton aide! J'ai essayé ton code mais ça ne fonctionne pas! Mais c'est pas grave un gars (Heyoan) m'a filé ce bout de code à mettre à la place du mien. Et ça marche!

 

Voici le code pour ceux que ça intéresse:

Code :
  1. $keywords = preg_split("/[\s,]+/", $text_search);
  2. if(count($keywords) > 0) {
  3. $search .= ' AND (';
  4. $prefix = '';
  5. for($i = 0; $i < count($keywords); $i++) {
  6. $search .= $prefix."a.ad_text LIKE '%".$keywords[$i]."%' ";
  7. $prefix = 'AND ';
  8. }
  9. $search .= ') AND a.published = 1';
  10. } else {
  11. $search .= ' AND a.published = 1';
  12. }


Message édité par hazmoon le 25-03-2009 à 12:38:50
Reply

Marsh Posté le 25-03-2009 à 13:00:59    

ouais enfin y'a explode sinon, plus que d'utiliser les PCRE :

Code :
  1. $words = explode(" ", $input);
  2.  
  3. foreach($words as $word) {
  4.    // ...
  5. }

Reply

Marsh Posté le 25-03-2009 à 13:18:39    

Explode ne pose pas un problème avec une chaine du style " fdf    fgfd           gfdgfd   gfd gdfgd    " ?


---------------
Tous les programmeurs sont des auteurs et tous les ordinateurs sont de mauvais acteurs.
Reply

Marsh Posté le 25-03-2009 à 13:36:04    

ouais, si tu veux :o
Mais bon, tu oublies que tu peux toujours rattraper çà (et même éviter de rechercher tous les caractères blancs) :

Code :
  1. foreach($words as $word) {
  2.    $tmp = trim($word);
  3.  
  4.    if(empty($tmp)) {
  5.        continue;
  6.    }
  7. }

Reply

Marsh Posté le 26-03-2009 à 15:42:02    

Je me permet de réouvrir la discussion, car en fait je rencontre quelques problèmes avec ce code:

Code :
  1. if(trim(preg_replace("/[\s,]+/", '', $text_search)) != '') {
  2. $keywords = preg_split("/[\s,]+/", $text_search);
  3. $keywords = array_unique($keywords);
  4. $search .= ' AND (';
  5. $prefix = '';
  6. for($i = 0; $i < count($keywords); $i++) {
  7.  $search .= $prefix."a.ad_text LIKE '%".$keywords[$i]."%' ";
  8.  $prefix = 'OR ';
  9. }
  10. $search .= ') AND a.published = 1';
  11. } else {
  12. $search .= ' AND a.published = 1';
  13. }


En effet, dans le code que j'ai posté sur le premier message de cette discussion, mon moteur de recherche cherchait dans deux champ ad_headline et ad_text.  
Mais comme vous pouvez le voir dans ce code qui m'a été fourni le champ ad_headline a été oublié. Comment faire pour que mon moteur cherche dans les deux champs?
Ce code fonctionne parfaitement, mais c'est simplement qu'il ne cherche pas dans ad_headline et je ne sais pas comment faire pour que mon moteur recherche dans les deux champs.
 
Si vous avez une idée?
 
Merci d'avance


Message édité par hazmoon le 26-03-2009 à 15:43:34
Reply

Marsh Posté le 26-03-2009 à 16:32:30    

En faisant une boucle et une variable différente pour chaque champ, et tu concatènes le tout à la fin.
Inspire du code que je t'avais donné... ( au passage pourquoi il ne marche pas ? :??: )

Message cité 1 fois
Message édité par DaSayan le 26-03-2009 à 16:33:14

---------------
Tous les programmeurs sont des auteurs et tous les ordinateurs sont de mauvais acteurs.
Reply

Marsh Posté le 26-03-2009 à 16:32:30   

Reply

Marsh Posté le 26-03-2009 à 17:13:13    

DaSayan a écrit :

En faisant une boucle et une variable différente pour chaque champ, et tu concatènes le tout à la fin.
Inspire du code que je t'avais donné... ( au passage pourquoi il ne marche pas ? :??: )


 
Beinh le problème avec ton code c'est que j'ai exactement le même problème qu'avec mon code de départ (voir premier message).

Reply

Marsh Posté le 27-03-2009 à 10:14:45    

hazmoon a écrit :

Beinh le problème avec ton code c'est que j'ai exactement le même problème qu'avec mon code de départ (voir premier message).


Bon ok...
 
Tu peux faire un truc comme ça, en gros :

Code :
  1. $prefix = '';
  2. $strText = '' ;
  3. $strHead = '' ;
  4.  
  5. for($i = 0; $i < count($keywords); $i++) {
  6.    $strText .= $prefix."a.ad_text LIKE '%".$keywords[$i]."%' ";
  7.    $strHead .= $prefix."a.ad_headline LIKE '%".$keywords[$i]."%' ";
  8.    $prefix = 'OR ';
  9. }
  10.  
  11. $search .= " AND (".$strText." ) AND (".$strHead." ) AND a.published = 1";

Il y aurai même mieux, parce que là on est limité à deux champs, et si tu veux en rajouter un troisième un jour tu va devoir modifier tout le script.
Le top serait une fonction où tu passe deux arguments : le string avec les mots, et un tableau avec les noms des champs où chercher. Et la boucle passe en revue le tableau pour faire la concaténation.
Mais là je te donne juste une piste, à toi de creuser  :hello:


---------------
Tous les programmeurs sont des auteurs et tous les ordinateurs sont de mauvais acteurs.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed