[MySQL] Recherche de mots dans un blob

Recherche de mots dans un blob [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 08-12-2005 à 15:53:05    

Bonjour à tous !
 
Voilà mon problème : je suis en train de faire une fonction de recherche de posts pour un forum.
Les messages sont stockés dans des blob.
 
Pour l'instant, tout ce que j'ai réussi à faire c'est ça comme requête :
 

Code :
  1. SELECT idmes, message
  2. FROM forum_messages
  3. WHERE message LIKE "%truc%" AND message LIKE "%machin%" AND message LIKE "%bidule%"
  4. ORDER BY idmes
  5. LIMIT 0,10


 
Mais ça me parait très lourd comme requête : comment pourrais-je faire plus simple svp ?
 
Merci d'avance :jap:


Message édité par nero27 le 08-12-2005 à 16:34:54
Reply

Marsh Posté le 08-12-2005 à 15:53:05   

Reply

Marsh Posté le 08-12-2005 à 16:58:37    

logiquement, t'as les fonction freetext et autres qui permettent de faire des recherches sur du texte.

Reply

Marsh Posté le 08-12-2005 à 18:51:52    

je suis tombé sur ça récemment, ca à l'air de trier par pertinence.
a voir si ca marche avec les blob ...
 
http://dev.mysql.com/doc/refman/5. [...] earch.html

Reply

Marsh Posté le 08-12-2005 à 20:01:15    

Y'a pas que "MATCH AGAINST", y'en a toute une floppée.
 
Je te conseille "FREETEXT" qui permet de faire une recherche plus naturelle (chaque mot de la phrase est pondéré de la même façon, ou suivant un dictionnaire de mots-clés, puis toutes les lignes correspondant à au moins un mot sont retournée avec un score. les mots "polluants" - le, des, c', etc. - sont ignorés avec cette méthode.)
 
Ainsi, si tu as dans ta table :
 
1 Le chat cours après la souris.
2 Les chiens détestent les chats, mais les chats aiment les souris.
3 Le chien est gris comme une souris.
4 Le fromage et le pain sont les plats de prédilection des souris.
 
Si tu recherches alors tu auras les lignes dans cette ordre :
 
"chiens et chats" :
2 "chiens" * 1 et "chats" * 2
1 "chat" * 1 (mal ortographié)
C'est tout : "et" est ignoré, donc  
 
"quand le chat est de sortie, les souris dansent"
2 "chats" * 2 (mal orthographié) "souris" * 1
1 "chat" * 1 et "souris" * 1
3 "souris" * 1
4 "souris" * 1, mais "noyé" dans un texte plus long, donc moins pertinant
les autres mots sont soit ignorés, soit absents, donc ne retournent pas de lignes.
 
En fait, avec un peu de boulot, tu peux faire un mini-google sans problème, et les performances sont très bonnes (en fait, l'indexation est lente, car le SGBD génère un lexique de tous les mots, avec champ lexical, synonymes et ortographes similaire, mais ensuite seul ce dictionnaire est interrogé pour faire la requête, ce qui évite de parcourir des millions de caractères pour rien)
 
Normalement, il y a aussi "CONTAINS" qui permet de pondérer les mots, ou forcer une orthographe similaire, et selon les SGBD, tu peux aussi avoir des fonction linguistiques qui te permettent de chercher dans d'autres langues (pour ça il faut définir une colonne langue, et posséder un fichier dictionnaire pour les traductions), ou les synonymes/antonimes (à nouveau, il faut un dictionnaire) et tout un tas d'autres fonctionnalités. Le moteur fulltext d'Oracle est particulièrement bien doté sur le sujet.

Reply

Marsh Posté le 08-12-2005 à 20:03:01    

Un petit exemple de résultat que ça donne avec SQL Server et un peu de boulot pour l'aider à comprendre des symboles de recherche :
http://www.manga-torii.com/default [...] erecherche
 
Comme tu peux voir, ça a beau être de l'ASP pas optimisé du tout, c'est hyper rapide (alors que la requête générée fait au moins 20 lignes :pt1cable:)
L'équivalent avec des "like" prenait plusieurs secondes et était bien moins pertinante !


Message édité par Arjuna le 08-12-2005 à 20:07:58
Reply

Marsh Posté le 09-12-2005 à 10:58:10    

Merci Arjuna, ta méthode est plutôt complète et je pense m'en servir plus tard, mais pour le moment, je pense que je vais utiliser la méthode de jeoff avec le FULLTEXT et en transformant mon blob en text.
 
Donc j'ai recréé la table de cette façon :

Code :
  1. CREATE TABLE `forum_messages` (
  2.   `idmes` bigint(20) NOT NULL auto_increment, //id des messages
  3.   `ids` int(11) NOT NULL default '0', //id du sujet lié
  4.   `idm` int(11) NOT NULL default '0', //id de l'auteur
  5.   `date` datetime NOT NULL default '0000-00-00 00:00:00', //date du message
  6.   `message` text NOT NULL, //contenu du message
  7.   `ip` varchar(15) NOT NULL default '', //ip de l'auteur au moment du post
  8.   PRIMARY KEY  (`idmes`),
  9.   KEY `ids` (`ids`,`idm`),
  10.   FULLTEXT (`message`)
  11. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;


 
J'ai ensuite posté ce message : "Test de la nouvelle table de stockage des messages !"
 
Puis j'ai utilisé cette requête pour faire une recherche sur le mot "test" comme ceci :

Code :
  1. SELECT *
  2. FROM `forum_messages`
  3. WHERE MATCH (
  4. message
  5. )
  6. AGAINST (
  7. "test"
  8. )


Seulement, ça ne me retourne aucun résultat :/
 
D'où celà peut-il provenir ? :??:


Message édité par nero27 le 09-12-2005 à 10:59:06
Reply

Marsh Posté le 09-12-2005 à 11:03:38    

Vérifie dans la doc MYSQL comment il rempli ses index des recherche sur texte.
 
En effet, le boulot d'indexation est particulièrement complexe et gourmand en ressources.
 
Par défaut, la plupart des SGBD ne font la reconstruction des index qu'à la demande.
 
Pire, s'ils estiment que depuis la dernière reconstruction il y a eu trop de mouvement dans les données, les index se verouillent et on ne peut plus les interroger.
 
Avec SQL Server par exemple, il faut paramètrer l'index comme tournant sur un serveur "dédié", afin de le forcer à se mettre à jour en temps réel, et cela ne dispense pas de faire une reconstruction complète par batch la nuit.
 
Avec Orace, la reconstruction ne peut être que manuelle.
 
Pour ces raisons, je suppose que MySQL fait pareil, il faut voir le paramétrage nécessaire pour allimenter les index.

Reply

Marsh Posté le 09-12-2005 à 11:18:11    

Citation :

Le seuil de 50% a un impact significatif lorsque vous commencez à comprendre comment fonctionne l'index : si vous créez une table et insérez une ou deux lignes, chaque mot apparaîtra dans 50% des lignes. Résultat, la recherche ne trouvera rien. Assurez-vous d'insérer au moins trois lignes, et même plus.


Je pense que ça vient de ça ;)
 
Je vais tester en mettant plus de messages.
 
EDIT: effectivement, ça fonctionne maintenant :jap:


Message édité par nero27 le 09-12-2005 à 11:20:01
Reply

Marsh Posté le 08-01-2006 à 11:06:04    

Salut à tous,
Ce topic est très intéressant et m'a appris 2 ou 3 truc.
Ma requete est:
$sk = addslashes($sk);
$req_sk = mysql_query("SELECT * FROM $table_images WHERE MATCH (keywords) AGAINST (\"$sk\" IN BOOLEAN MODE)" );
 
Mais comment fait-on pour que le résultat soit trié par pertinence?
Je souhait que quand on met 2 mots alors quand ils sont là les 2 viennent en premier puis ensuite ceux ou il y en a qu'un.

Reply

Marsh Posté le 08-01-2006 à 11:25:55    

Il me semble que par défaut, c'est trié par pertinence, non ?
(je n'en suis pas sûr du tout)

Reply

Marsh Posté le 08-01-2006 à 11:25:55   

Reply

Marsh Posté le 09-01-2006 à 14:07:02    

Comme j'ai compris, oui, mais quand je teste, non.

Reply

Marsh Posté le 17-05-2006 à 20:55:14    

Bonsoir,
 
j'ai un pb avec match et against.
j'ai ces deux champs :
 

Code :
  1. Les Rivières Pourpres 2...
  2. Old Boy Edition spéciale...


 
si je fait une recher sur "rivieres pourpres", pas ed soucis je récupère le bon titre.
Si je tape Old Boy, rien du tout.
 
Comment cela se faisse ?
 
merci :hello:


Message édité par $man le 17-05-2006 à 20:56:43
Reply

Sujets relatifs:

Leave a Replay

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