Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2356 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [Résolu] Pertinence. MATCH/AGAINST

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Résolu] Pertinence. MATCH/AGAINST

n°1987967
VinceA
Posté le 27-04-2010 à 12:09:39  profilanswer
 

Bonjour à tous =).
 
Je suis actuellement sur un projet scolaire qui consiste à dév. un moteur traitant une "Recherche multicritères".
Dans ces critères figurent : Nom, auteur, éditeur, parution.. (On parle ici de Livre/CD/DVD/Revue).
 
J'ai 4 tables (une pour chaque type de document [livre, cd..]) avec une structure qui est à quelques champs près, la même pour toutes.
 
J'en viens au fait :
Ma recherche MULTICRITERES contient un critère "mots-clés"... Le gars saisit des mots-clés et on va faire la recherche sur les champs nom(titre)/auteur/description, pour chaque mot avec un %LIKE%...
 
Seulement j'aimerais faire un tri par pertinence, et j'ai vu que l'engine MyIsam gérait ça avec MATCH/AGAINST en mode FULLTEXT.
J'ai donc indexé mes champs nom,auteur,description en FULLTEXT pour chaque table (livre, cd, dvd, revue).
 
Voilà la tête de ma requête, quand la personne qui effectue la recherche ne précise pas le type de documents :
Avant de découvrir Match/Against

Code :
  1. SELECT * from (SELECT livre.id, livre.nom, livre.auteur, livre.description, livre.type_document FROM livre UNION SELECT cd.id, cd.nom, cd.auteur, cd.description, cd.type_document FROM cd UNION SELECT dvd.id, dvd.nom, dvd.auteur, dvd.description, dvd.type_document FROM dvd UNION SELECT revue.id, revue.nom, revue.auteur, revue.description, revue.type_document FROM revue) AS data WHERE (data.nom LIKE '%fourmis%' OR data.nom LIKE '%werber%' OR data.auteur LIKE '%fourmis%' OR data.auteur LIKE '%werber%' OR data.description LIKE '%fourmis%' OR data.description LIKE '%werber%');


 
Je suis obligé de chercher dans livre ET cd ET dvd ET revue, puis faire un groupe de 3 OR (3 champs, logique) pour chaque mot-clé saisi (ici, "fourmis" et "werber" ).
 
Avec Match et Against, voici à quoi c'est censé ressembler :

Code :
  1. SELECT * from (SELECT livre.id, livre.nom, livre.auteur, livre.description, livre.type_document FROM livre UNION SELECT cd.id, cd.nom, cd.auteur, cd.description, cd.type_document FROM cd UNION SELECT dvd.id, dvd.nom, dvd.auteur, dvd.description, dvd.type_document FROM dvd UNION SELECT revue.id, revue.nom, revue.auteur, revue.description, revue.type_document FROM revue) AS data WHERE MATCH(data.nom, data.auteur, data.description) AGAINST('fourmis lune rouge');


 
Et en plus j'ai un tri par pertinence (le + d'occurences en premier), la classe.
Seulement voilà :
ERROR 1191 (HY000) : Can't find FULLTEXT index matching the column list.
 
Quand je fais quelque chose comme

Code :
  1. SELECT * from livre WHERE MATCH(livre.nom, livre.auteur, livre.description) AGAINST('fourmis werber');


Il n'y a pas de soucis.
 
Je pense que MySQL cherche à fouiner dans "data.nom" alors que ce n'est que l'assemblage du champ Nom de mes 4 tables, et donc dit que "data.nom" n'est pas indexé en FULLTEXT (normal 'data' est un alias et non une table...).
 
J'ai bien essayé le "IN BOOLEAN MODE" dans Against, qui permet de faire ça sans FULLTEXT, mais ici la pertinence n'est plus :/.
 
Désolé pour le pavé j'ai essayé de détailler un maximum...
Merci d'avance.
 
Amicalement,
Vincent.
 
EDIT solution trouvée ^^

Code :
  1. SELECT * FROM
  2. (SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM livre WHERE MATCH(nom, auteur, description)AGAINST('astronomie soleil étoile')
  3. UNION
  4. SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM dvd WHERE MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile')
  5. UNION
  6. SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM cd WHERE MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile')
  7. UNION
  8. SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM revue WHERE MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile')
  9. ) a ORDER BY score DESC;


 
Merci à flo850 pour son aide =) !


Message édité par VinceA le 27-04-2010 à 15:12:38
mood
Publicité
Posté le 27-04-2010 à 12:09:39  profilanswer
 

n°1987972
flo850
moi je
Posté le 27-04-2010 à 12:15:28  profilanswer
 

est ce que tu ne devrai pas plutot faire  

Code :
  1. SELECT livre.id, livre.nom, livre.auteur, livre.description, livre.type_document, MATCH(DATA.nom, DATA.auteur, DATA.description) AGAINST('fourmis lune rouge') AS score  FROM livre WHERE MATCH(livre.nom, livre.auteur, livre.description) AGAINST('fourmis lune rouge')
  2.  
  3. UNION
  4. SELECT dvd.id, dvd.nom, dvd.auteur, dvd.description, dvd.type_document, MATCH(dvd.nom, dvd.auteur, dvd.description) AGAINST('fourmis lune rouge') AS score  FROM dvdWHERE MATCH(dvd.nom, dvd.auteur, dvd.description) AGAINST('fourmis lune rouge')


n°1987977
VinceA
Posté le 27-04-2010 à 12:28:04  profilanswer
 

@flo850 : Oh oui ! Trop con, pourquoi j'y ai pas pensé lol... ça a l'air de marcher, je vous tiens au jus !
 
Si quelqu'un a une opti pour que ça soit "moins long" je suis preneur ;).
 
En attendant merci beaucoup flo ^^

n°1987991
flo850
moi je
Posté le 27-04-2010 à 13:37:57  profilanswer
 

En moins long, tu peux esasyer de factoriser tes tables  
article(id,nom,id_auteur,description,type)
avec type qui est une enum de dvd,livre,revue

n°1988013
VinceA
Posté le 27-04-2010 à 14:24:14  profilanswer
 

Nio ? Je connaissais pas cette méthode... J'vais devoir refaire un p'tit tour de leçon sur le site de MySQL moi (ou alors je comprends mal ce que tu veux dire ^^).
 
En tout cas ça a l'air de marcher, merci énormément =).

n°1988018
flo850
moi je
Posté le 27-04-2010 à 14:28:32  profilanswer
 

tu as trois tables avec sensiblement les mêmes champs
 
pourquoi ne pas faire une seule table ?

n°1988036
VinceA
Posté le 27-04-2010 à 14:55:29  profilanswer
 

Parce que certaines comme CD ou DVD ont des champs spéciaux genre "nbdisque", "nbpiste".. Puis c'est un projet scolaire donc faut éviter les bricolages à la "tous ces champs à NULL si jamais c'est pas un cd ou un dvd"...
 
D'ailleurs j'constate un soucis avec la méthode SELECT UNION SELECT ... C'est qu'il fait la pertinence SELECT par SELECT, et pas sur l'ensemble des tables... :S... T'as une solution ? :P  
 
Merci

n°1988042
VinceA
Posté le 27-04-2010 à 15:08:21  profilanswer
 

EDIT :
 
C'est bon en fait !! :D

Code :
  1. SELECT * FROM
  2. (SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM livre WHERE MATCH(nom, auteur, description)AGAINST('astronomie soleil étoile')
  3. UNION
  4. SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM dvd WHERE MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile')
  5. UNION
  6. SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM cd WHERE MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile')
  7. UNION
  8. SELECT nom, auteur, description, MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile') AS score FROM revue WHERE MATCH(nom, auteur, description) AGAINST('astronomie soleil étoile')
  9. ) a ORDER BY score DESC;


Merci beaucoup l'ami ^^


Message édité par VinceA le 27-04-2010 à 15:13:26
n°1988083
rufo
Pas me confondre avec Lycos!
Posté le 27-04-2010 à 16:02:07  profilanswer
 

VinceA a écrit :

Parce que certaines comme CD ou DVD ont des champs spéciaux genre "nbdisque", "nbpiste".. Puis c'est un projet scolaire donc faut éviter les bricolages à la "tous ces champs à NULL si jamais c'est pas un cd ou un dvd"...
[...]
 
Merci


 
Tu fais une table "objet" qui contient les attributs communs, dont un qui sera l'enum définissant le type (cd, dvd, livre...) et une table attributs spécifiques dont le contenu va ressembler à ça :
ID
Nom attribut
Valeur attribut
Type attribut (entier, float, champ text, blob...)
 
Entre les 2 tables, y'a une relation N-N. Regardes Mantis ou Magento comme softs GPL qui implémente cette possibilité de rajouter des attributs à des objets...
 
Par contre, ça complexifie les requêtes SQL mais ça rend ton modèle très générique ;)


Message édité par rufo le 27-04-2010 à 16:02:41

---------------
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
n°1988120
VinceA
Posté le 27-04-2010 à 16:48:22  profilanswer
 

C'est une bonne idée en effet !
 
Par contre j'ai une colle... Pourquoi un mysql_query() retourne moins de résultat que la requête directement balancée dans MySQL Server (sous console) xD ?
 
C'est un problème "annexe", je m'en chargerais plus tard ^^.
 
Je vais voir pour finir un premier jet de mon projet puis apporter ces modifications de structure à mes tables ! :)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [Résolu] Pertinence. MATCH/AGAINST

 

Sujets relatifs
[RESOLU]Plus de "insérer un commentaire" après la macro[Résolu][php]récupération de données d'un fichier .txt
[Résolu] Bug: le texte est gros aléatoirement...Macro oublie des cellules [Résolu]
LTI-LIB: Problèmes d'installation [Résolu][RESOLU]Accéder méthode ou objet autre Frame
[resolu] Probleme de syntaxe dans un UPDATEPb margin-top : 2 éléments côte-à-côte se chevauchent!
[RESOLU] mysqldump, php et dump vide :(UserForm et Barre de progression [Résolu]
Plus de sujets relatifs à : [Résolu] Pertinence. MATCH/AGAINST


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR