osCommerce France : Accueil Forum Portail osCommerce France Réponses aux questions Foire aux contributions

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> RESOLU - Recherche par mot exact
diaph
posté 23 Aug 2013, 08:53
Message #1


Ceinture jaune+ OSC
Icône de groupe

Groupe : Membres
Messages : 153
Inscrit : 22-October 07
Membre no 19482



smile.gif Bonjour,
Serait-il possible, et assez facile de faire un champ pour mot exact : pour éviter l'affichage de produits qui ne correspondent pas à la demande ?
En fait, si je tape "lait", je ne veux pas voir tout les produits avec "laitage", si ce mot est compris dans la description. A savoir que je fais une recherche dans les descriptions (case cochée).
Dans "advanced_search.php, j'ai:
Code
if ( ((keywords == '') || (keywords.length < 1)) && ((dfrom == '') || (dfrom == '<?php echo DOB_FORMAT_STRING; ?>') || (dfrom.length < 1)) && ((dto == '') || (dto == '<?php echo DOB_FORMAT_STRING; ?>') || (dto.length < 1)) && ((pfrom == '') || (pfrom.length < 1)) && ((pto == '') || (pto.length < 1)) ) {
    error_message = error_message + "* <?php echo ERROR_AT_LEAST_ONE_INPUT; ?>\n";
    error_field = document.advanced_search.keywords;
    error_found = true;
  }

Dans "advanced_search_result.php, j'ai:
Code
if (isset($search_keywords) && (sizeof($search_keywords) > 0)) {
    $where_str .= " and (";
    for ($i=0, $n=sizeof($search_keywords); $i<$n; $i++ ) {
      switch ($search_keywords[$i]) {
        case '(':
        case ')':
        case 'and':
        case 'or':
          $where_str .= " " . $search_keywords[$i] . " ";
          break;
        default:
          $keyword = tep_db_prepare_input($search_keywords[$i]);
          $where_str .= "(pd.products_name like '%" . tep_db_input($keyword) . "%' or p.products_model like '%" . tep_db_input($keyword) . "%' or m.manufacturers_name like '%" . tep_db_input($keyword) . "%'";
          if (isset($HTTP_GET_VARS['search_in_description']) && ($HTTP_GET_VARS['search_in_description'] == '1')) $where_str .= " or pd.products_description like '%" . tep_db_input($keyword) . "%'";
          $where_str .= ')';
          break;
      }
    }
    $where_str .= " )";
  }

Je n'ai pas trouvé de modifs sur le forum...
Merci

Ce message a été modifié par diaph - 25 Aug 2013, 19:41.


--------------------
J'utilise OScommerce MS2.2 (modifié pour php5) - Ebergeur LWS - Download Controller - Contrib PayPal IPN
Machine Mac Pro - Lion 10.7. 5 - Mamp
Go to the top of the page
 
chti_poupon
posté 23 Aug 2013, 14:17
Message #2


Ceinture noire OSC
Icône de groupe

Groupe : TechDev
Messages : 2744
Inscrit : 9-September 08
Lieu : Douai
Membre no 22915



Bonjour
-Dans ce cas (description), si tu remplaces
Code
if (isset($HTTP_GET_VARS['search_in_description']) && ($HTTP_GET_VARS['search_in_description'] == '1')) $where_str .= " or pd.products_description like '%" . tep_db_input($keyword) . "%'";
par
Code
if (isset($HTTP_GET_VARS['search_in_description']) && ($HTTP_GET_VARS['search_in_description'] == '1')) $where_str .= " or pd.products_description like '" . tep_db_input($keyword) . "'";

La sélection sera plus sévère, même trop.
En fait, ces lignes préparent une requête SQL et utilisent les commandes SQL.

Chti poupoo
Go to the top of the page
 
diaph
posté 23 Aug 2013, 15:08
Message #3


Ceinture jaune+ OSC
Icône de groupe

Groupe : Membres
Messages : 153
Inscrit : 22-October 07
Membre no 19482



Merci pour ta réponse.
Cela ne fonctionne pas; j'ai un "warning" : Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/loging/www/advanced_search_result.php:3) in /home/loging/www/includes/functions/sessions.php on line 97
dir="LTR" lang="fr"
???? encodage ????

Ce message a été modifié par diaph - 23 Aug 2013, 15:17.


--------------------
J'utilise OScommerce MS2.2 (modifié pour php5) - Ebergeur LWS - Download Controller - Contrib PayPal IPN
Machine Mac Pro - Lion 10.7. 5 - Mamp
Go to the top of the page
 
chti_poupon
posté 23 Aug 2013, 17:18
Message #4


Ceinture noire OSC
Icône de groupe

Groupe : TechDev
Messages : 2744
Inscrit : 9-September 08
Lieu : Douai
Membre no 22915



Où as-tu mis cette modification ? Dans advanced_search_result.php, je présume vers la ligne 266 ?
Alors je ne comprends pas cette erreur qui n'a rien à voir a priori avec la recherche détaillée mais plutôt avec la FAQ (ton amie trop délaissée ici).
Repartir de l'index et tester sans omettre de cocher la case "description" me paraît indispensable, après avoir testé le fonctionnement normal du site !
Bon code !
Chti poupon

Go to the top of the page
 
diaph
posté 23 Aug 2013, 18:29
Message #5


Ceinture jaune+ OSC
Icône de groupe

Groupe : Membres
Messages : 153
Inscrit : 22-October 07
Membre no 19482



Merci pour le lien ... smile.gif
J'avais l'éditeur Kompozer, j'ai pris Xcode et j'ai résolu mon problème de ligne ; donc plus de warning.
En revanche la modif ne fonctionne toujours pas : il ne trouve rien dans les descriptions (case cochée), quel que soit le mot...
Bizarre huh.gif


--------------------
J'utilise OScommerce MS2.2 (modifié pour php5) - Ebergeur LWS - Download Controller - Contrib PayPal IPN
Machine Mac Pro - Lion 10.7. 5 - Mamp
Go to the top of the page
 
chti_poupon
posté 24 Aug 2013, 09:24
Message #6


Ceinture noire OSC
Icône de groupe

Groupe : TechDev
Messages : 2744
Inscrit : 9-September 08
Lieu : Douai
Membre no 22915



Bonjour
C'était écrit !
En fait, l'expression
LIKE %toto% cherche n'importe quoi ayant la chaîne toto dans son contenu (ex: "bébé a fait ses rototos")
LIKE toto% cherche n'importe quoi commençant par toto (ex:"toto est sage")
LIKE %toto cherche n'importe quoi finissant par toto (ex:"dans tes cheveux, j'ai vu un toto")
LIKE toto cherche exactement toto sans rien avant ni après.

Sur cette base, il est possible d'imaginer chercher
LIKE '% ' . tep_db_input($keyword) . ' %' soit le mot exact avec un espace avant et après qui pourrait être pertinent selon le contexte.
Bons essais !
Chti poupon
Go to the top of the page
 
FoxP2
posté 24 Aug 2013, 18:42
Message #7


Ceinture marron OSC
Icône de groupe

Groupe : Modérateurs
Messages : 1665
Inscrit : 3-June 09
Membre no 25501



Lorsque vous écrivez :
SQL
select products_name, products_description
from products_description where (products_name like %keywords% or products_description like %keywors%)


Fonctionnellement cette requête n'est pas une recherche par mots mais pas caractères.
De plus elle ne permet pas de classement par pertinence, ni de doser la force des différents mot clés.

Techniquement, cette requête force le sgbd à analyser le contenu entier de tous les champs products_description de la table, ce qui peut être long et coûteux.
De plus, ces champs peuvent contenir
- de nombreux mots sans aucune valeur (la, le, les, et ...)
- des mots qui se répètent

Il y a une autre façon de faire pour mettre en place un vrai moteur de recherche, à la google, dans une boutique.
A vous de voir laquelle, en réflechissant un peu, et surtout, en vous documentant.


--------------------


Go to the top of the page
 
diaph
posté 25 Aug 2013, 19:35
Message #8


Ceinture jaune+ OSC
Icône de groupe

Groupe : Membres
Messages : 153
Inscrit : 22-October 07
Membre no 19482



smile.gif Bonjour,
J'ai résolu une partie de mon problème, comme ceci :

Code
if (isset($HTTP_GET_VARS['search_in_description']) && ($HTTP_GET_VARS['search_in_description'] == '1')) $where_str .= " or pd.products_description like '%(espace)" . tep_db_input($keyword) . "(espace)%'";


En mettant un espace avant et après les guillemets, emplacement indiqué (espace) dans le code ci-dessus. C'est la seule ligne que j'ai modifiée (265) dans advanced_search_result.php.

Il y a encore quelques petites anomalies, mais sans gravitée ; dans l'ensemble ça fonctionne pour moi, je peux même chercher plusieurs mots "exact", le tri ce fait bien...

Merci à vous pour vos aides et suggestions.




--------------------
J'utilise OScommerce MS2.2 (modifié pour php5) - Ebergeur LWS - Download Controller - Contrib PayPal IPN
Machine Mac Pro - Lion 10.7. 5 - Mamp
Go to the top of the page
 
chti_poupon
posté 25 Aug 2013, 21:09
Message #9


Ceinture noire OSC
Icône de groupe

Groupe : TechDev
Messages : 2744
Inscrit : 9-September 08
Lieu : Douai
Membre no 22915



Bonjour,
C'est bien ce que j'avais mis - sans souligner les espaces - mais FoxP2 a raison: la vraie recherche passe par l'utilisation d'index FULLTEXT pour indexer les colonnes de recherche concernées.
Malheureusement, elles sont dispersées dans différentes tables et il faut préalablement créer une vue avant de faire la recherche.(la documentation est )
Ceci bien que MySQL soit limité: c'est fort instructif et puissant.
J'y travaille (entr'autres)
Chti poupon
Go to the top of the page
 
Gnidhal
posté 30 Aug 2013, 21:30
Message #10


5eme dan OSC
Icône de groupe

Groupe : Administrateur
Messages : 9221
Inscrit : 4-March 03
Lieu : Auray
Membre no 927



Alors oui et non, en fait ça dépend du catalogue et du type de recherche souhaité.

Pour des bouquins on serait tenté de penser qu'on veut une recherche globale incluant le titre et le texte descriptif : pas forcément et pas efficace sauf dans des cas particuliers.
Pour des pièces auto on pourrait souhaiter une recherche étendu sur la marque, le modèle, la cylindrée : autre sujet mais dans ce cas ça devient très complexe sauf si le nom produit contient toutes ces infos.

la recherche FULLTEXT associée à l'option WITH QUERY EXPANSION devrait donner des résultats assez sympas sur la pertinence et les similarités mais, malgré une indexation des champs en FULLTEXT, cela reste lourd et lent.
J'ai fait plusieurs essais sur un système de recherche en Ajax qui nécessite donc des temps de réponse le plus court possible et la recherche FULLTEXT bien que très puissante ne donne pas forcément des résultats très pertinents.
J'ai donc choisi de créer un moteur de recherche se limitant aux titres ou aux noms de produits en essayant d'inclure le maximum d'informations pertinentes dans le nom ou titre.
Le but était de retourner un résultat pertinent même avec des mots dans le désordre.
exemple concret avec un titre de livre : "3 minutes pour comprendre les 50 plus grandes théories en Psychologie"
Si je cherche $w = "les grandes théories" avec une requête du type pd.products_name LIKE '%$w%' le bouquin en exemple n'est pas trouvé alors qu'il le sera avec une requête du type MATCH (pd.products_name) AGAINST ('$w' WITH QUERY EXPANSION).
Mais cette requête MATCH/AGAINST me retourne aussi d'autres ouvrages en priorité avec dans le titre "les grandes" : pas très adapté et plus lent.
J'ai donc cherché un procédé plus efficace uniquement sur les titres.
La méthode consiste à séparer les mots clé dans la chaine recherchée puis à associer les recherches avec LIKE et des jokers ce qui donne un truc de ce genre :
Code
   $q = strtr($q, "àáâãåçèéêëìíîïñòóôõøùúû", "aaaaaceeeeiiiinooooouuu");    // suppression des principaux accents pour éliminer ensuite tous les caractères non-alphanumériques
   $q = preg_replace('`[^0-9a-z\-\s\']`i','',$q);
   $q= trim(tep_db_input($q)); //on nettoie la chaine de recherche et supprime les espaces devant et derrière
   $and_p = '';

   if (preg_match('`^[0-9-]{3,17}$`', $q) ){      //  pour ne cibler que les ISBN si on a une recherche par N°
       $qn = preg_replace('`[^0-9]`','',$q);
       $and_p .= " and p.products_ISBN LIKE '%$qn%' ";
    }else{    
     $words = explode(' ',$q);
     foreach ($words as $w){
       if (strlen($w)>1){ // on ne tient pas compte des lettres isolées
         if (strlen($w)<=3)$w = " $w "; // les articles isolés sont pris en compte avec l'ajout d'espage pour les mots de 2 et 3 lettres: le la les des....
         $and_p .= "and pd.products_name LIKE '%$w%' ";
       }
     }
   }
// la requête enrichie d'options particulières comme categories_status afin de ne pas prendre en compte les produits dans les catégories cachées et un résultat limité à 16 (le résultat est retourné en ajax)
     $sql = "SELECT p.products_id, p.products_image, p.products_ISBN, pd.products_name FROM products_description pd, products p, products_to_categories p2c left join categories c on (c.categories_id = p2c.categories_id) WHERE c.categories_status = '1' and p.products_id = pd.products_id and p2c.products_id = p.products_id and p.products_status='1' and pd.language_id = '" . (int)$languages_id . "' $and_p group by products_id LIMIT 16";

la requête s'enrichit au cours de la frappe en tenant compte de chaque mot existant dans le titre, et ce quel que soit l'ordre des mots saisis : ça fonctionne plutôt pas mal !
en syntaxe, la recherche ajoute des conditions au cours de la frappe ce qui peut donner " and pd.products_name LIKE '%compr%' and pd.products_name LIKE '%theori%' and pd.products_name LIKE '%psychologie%' "
Je peux placer les mots dans le désordre, le filtre se construit au fur et à mesure de la frappe :
"comprend psychologie grand théori" me retourne ce titre exactement car c'est le seul qui contient tous ces mots partiels

Le seul bémol que j'ai rencontré concerne les chiffres et nombres qui peuvent être saisis dans la recherche en texte ou en chiffre, et si je cherche "les cinquante" ça ne trouvera pas ce titre alors que si je cherche "les 50" (à condition que ce ne soit un chiffre en début de la chaine de recherche, à cause du filtrage pour recherche par ISBN) je trouve.
J'ai pensé à faire un thesaurus pour les chiffres et nombres mais là, ça devient lourd car en écrivant "3", je dois chercher "3" ou "trois" : pour les 10 premiers nombres, ça peut le faire mais si on imagine "quatorze" "trente-sept" "deux mille trois cent soixante neuf" et autre nombre en texte, ça devient ingérable.
Cela dit, si vous connaissez une solution pour gérer les nombres texte/chiffre sur la base d'une fonction existante, je suis preneur

Voilà c'était un peu d'eau au moulin des moteurs de recherche basé sur l'expérience plutôt que sur la science.
Un vrai moteur de recherche devrait pouvoir s'affranchir des fautes d'orthographe ou de frappe comme le fait Google par exemple, mais pour ça je n'ai pas trouvé de documentation sur des fonctions SQL adaptées.
J'ai bien essayé de faire un soundex en ajoutant à chaque fiche un champ contenant le soundex du titre (et donc sur lequel on appliquerait in LIKE sur chaque mot de la recherche en soundex) mais ça n'est pas efficace... et cela se limite vraiment à des champs textes et n'a pas de pertinence pour des champs de type BLOB ou TEXT


--------------------
Tout d'abord : - Ni Hotline ni Service Après Vente, ces forums sont un lieu d'échange. BIEN POSER SA QUESTION (généralités)
Les "Informations Importantes" que vous devez ABSOLUMENT avoir lues :
Règlement, Bien poser sa question dans ces forums et Bien utiliser les Forums.
Les raccourcis pour gagner du temps : la FAQ, les PDF de la Doc (MS2-fr): PDF-V1 et PDF-V2, le moteur de Recherche sur les forums , la Liste des Contributions de Corbin.

----------------------------- Quelques sites de référence ---------------------------
PHP: Le site du Zéro et PHP Débutant avec la DOC en français -- HTML: Self HTML - WebProgrammation -- CSS: OpenWeb - AlsaCréations - CSS/Edge -- Autres ressources: - XajaX - highslide js
Les bons outils : EasyPHP - WAMP-5 - - Notepad++ - Firefox et son extension WebDeveloper
Le gène idéal c'est le gène original. Le génie des halles est un Génie des Alpages qui tente d'être à la page. (Merci f'murrr pour les cours de philosophie de chien)
Go to the top of the page
 

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



RSS Version bas débit Nous sommes le : 17th September 2019 - 00:45
Ce site est déclaré auprès de la commision Nationale
de l'Informatique et des Libertés (déclaration n°: 1043896)