Page 1 sur 1

Moteur recherche & stockage texte caractère spéciaux htm

Posté : 25 sept. 2006, 18:24
par antoine.webmaster
Salut,

excusez du titre un peu long, j'ai pas eu le choix :)

je travaille actuellement à un petit moteur de recherche sur un site en php/mysql

et je me trouve confronté à ce problème :

je stocke mes données texte dans la base, aprés avoir transformé tous les caractères spéciaux dans leur equivalent html, ceci à l'aide de la fonction php : htmlentities() ce que tout le monde conseille apparemment...

j'ai ensuite un champ de recherche, dont je récupère la valeur (aprés l'avoir passée par htmlentities), et que j'envois dans une requete mysql de type fulltext (bien pratique pour la pertinence des résultats!)

jusque là tout va bien, si je recherche étoile (avec un accent), et que le mot étoile est trouvé dans la base, ca marche

MAIS si je recherche etoile (sans accent!!!) je n'ai bien entendu aucuns résultat

hors, je pense qu'il y'a plus de probalilité que les visiteurs fassent des recherches sur des expressions sans les accents que le contraire

mon moteur n'est donc pas valide !

je me dis qu'il y'a peut être une fonction dispo dans mysql qui permet de passer outre ce problème, du genre -> une requete qui serait capable de comparer l'expression voulue avec celles contenues dans la base AVEC et SANS les caractères spéciaux (le é serait remplacé par le e, è par e, ç par c ...etc...)

j'ai bien cherché dans les fonctions sur les chaines de caractère de mysql, mais je n'ai rien trouvé

et vous, comment faites vous ?

Clt,
Antoine

Re: Moteur recherche & stockage texte caractère spéciaux

Posté : 25 sept. 2006, 20:40
par hbellahc
Voila ,je te file une fonction qui remplace toutes les lettres accentuées dans une chaîne de caractères
function OterAccents($chaine) {
return(strtr( $chaine,
"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ",
"AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn" ) );
}
Normalement toutes les lettres sont incluses ,si tu vois d'autres qui manquent ,tu les rajoutes
bon courage

Posté : 25 sept. 2006, 20:53
par antoine.webmaster
merci pour la fonction,

j'ai peur de m'être mal exprimé, car elle ne correspond pas à mon problème...

le texte que je stocke dans mysql se présente comme ceci :

étoile

ce qui, lors d'une recherche fulltext, pose le probleme des expressions que l'on a saisie sans accent, comme celà :

etoile

du coup, les résultats de la recherche ne sont pas cohérents...car je pense que la plupart des utilisateurs ne saisissent pas les accents lors d'une recherche...

je peux donner un exemple de code si vous voulez...

Posté : 25 sept. 2006, 21:19
par hbellahc
Ah d'accord ,excuses j'ai mal compris
Je vois le problème ,il y a peut être une solution ,si tu utilise la fonction réversible html_entity_decode() manuel ici,à partir d'un code html (étoile) tu obtient (étoile)
Mais ce traitement tu dois le faire sur le contenu de ta base ,donc ça va ralentir la vitesse de ta recherche.
enfin je ne sais pas ,regardes un peut ce qu'elle fait peut être tu trouveras une solution
bon courage

Posté : 25 sept. 2006, 23:31
par Invité
Pas grave...

cette fonction pourrait éventuellement convenir, mais c'est une fonction PHP

il faudrait donc faire un select sur champs requis, puis y appliquer la fonction

hors, dans mon cas c'est une requete mysql avec l'option fulltext

la recherche et la comparaison avec l'expression se font donc directement en mysql, et renvoi un classement de résultats pertinents en fonction du nombre d'occurence de l'expression trouvé dans la base

il faudrait donc un peu l'equivalent de html_entity_decode() mais en mysql...( si je ne me trompe pas )...

Posté : 26 sept. 2006, 09:18
par zeus
ou alors, que tu fasses un htmlentities() sur ce que tu va rechercher dans ta requete ;)

Posté : 26 sept. 2006, 13:20
par antoine.webmaster
comment vois tu ca, zeus ?

je crois que je n'ai pas expliqué de facon assez détaillée ma démarche,
à ma connaissance, il n'est pas possible d'intégrer htmlentities dans une requete sql...

car c'est bel et bien sur le contenu de la base que j'ai besoin d'effectuer cette action et ce, à l'interieur d'une requete sql

connaissez vous les requêtes FULLTEXT de mysql ?

voici ma requête :

Code : Tout sélectionner

SELECT *, MATCH (libelle, description) AGAINST ('".$recherche."') as cpt FROM article

libelle et description sont les 2 champs de la base sur lesquels je veux que la recherche s'effectue

$recherche est le champ saisi par l'internaute

le résultat de cette requete donne les enregistrements contenant l'expression $recherche

(avec la possibilité par la suite de les classer suivant le nombre d'occurences trouvées pour chaque enregistrement, c'est tout l'intérêt de cette formule)


dans les champs libelle et description, le texte est enregistré avec les equivalents html
le mot étoile, s'y trouve donc sous cette forme : étoile
alors, si je recherche etoile (sans accent)
la requete ne trouve rien, mon moteur n'est donc pas valide...

est ce un peu plus clair ?

Posté : 26 sept. 2006, 23:08
par hbellahc
comment vois tu ca, zeus ?

je crois que je n'ai pas expliqué de facon assez détaillée ma démarche,
à ma connaissance, il n'est pas possible d'intégrer htmlentities dans une requete sql...

car c'est bel et bien sur le contenu de la base que j'ai besoin d'effectuer cette action et ce, à l'interieur d'une requete sql

connaissez vous les requêtes FULLTEXT de mysql ?

voici ma requête :

Code : Tout sélectionner

SELECT *, MATCH (libelle, description) AGAINST ('".$recherche."') as cpt FROM article

libelle et description sont les 2 champs de la base sur lesquels je veux que la recherche s'effectue

$recherche est le champ saisi par l'internaute

le résultat de cette requete donne les enregistrements contenant l'expression $recherche

(avec la possibilité par la suite de les classer suivant le nombre d'occurences trouvées pour chaque enregistrement, c'est tout l'intérêt de cette formule)


dans les champs libelle et description, le texte est enregistré avec les equivalents html
le mot étoile, s'y trouve donc sous cette forme : étoile
alors, si je recherche etoile (sans accent)
la requete ne trouve rien, mon moteur n'est donc pas valide...

est ce un peu plus clair ?
Est ce que tu ne peut pas rajouter deux champs dans table (libele1 et description1) avec du texte obtenu avec la fonction que je t'ai donné sur tes champs (libele et description) ensuite tu fait ton MATCH sur eux ?

Posté : 26 sept. 2006, 23:35
par antoine.webmaster
en effet !

j'osais espérer qu'il existe une fonction mysql permettant de passer outre ce formatage de texte...

mais dans l'impossibilité de faire autrement je créerais des champs "clones" dédiés uniquement à la fonction de recherche

merci

Posté : 27 sept. 2006, 01:40
par Hubert Roksor
j'osais espérer qu'il existe une fonction mysql permettant de passer outre ce formatage de texte...
Je fais court parce que je crois que vous avez déjà pas mal cerné la question mais non, ça n'existe pas [encore] à ma connaissance. Dans un futur plus ou moins proche sous MySQL 5.1 ça dépendra du moteur de recherche utilisé (le traditionnel "Full-text" ou d'autres), mais dans l'immédiat il te faudra recourir à une représentation intermédiaire (en d'autres termes: un copie du texte sans accents) si tu veux chercher à la fois les caractères accentués et non-accentués.

À la rigueur, tu peux essayer de faire une recherche FULLTEXT sur quelque chose comme: (à vérifier, je ne sais plus si "?" fonctionne en full-texte, sinon il faut utiliser "*")

Code : Tout sélectionner

SELECT * FROM table WHERE MATCH (champs) AGAINST ('?toile')
ou encore (à vérifier aussi)

Code : Tout sélectionner

SELECT * FROM table WHERE MATCH (champs) AGAINST ('*toile') AND champs RLIKE '[eé]toile'
où "MATCH ... AGAINST" permet de trouver tous les enregistrements potentiels et RLIKE permet ensuite d'écarter les faux-positifs tels que "rtoile" par exemple). C'est loin d'être idéal, mais c'est le plus simple à moins de dupliquer le contenu du champs.

Posté : 27 sept. 2006, 01:42
par Hubert Roksor
Au fait, mon exemple est nul parce qu'un mot-clé qui commence par un joker * n'utilisera pas l'index Full-text (qui a besoin de l'initiale du mot pour être utilisé) alors remplacez étoile/*toile par forêt/for*t dans mon exemple ;)

Posté : 27 sept. 2006, 11:54
par antoine.webmaster
Merci pour la confirmation (...snif....)

si je comprends bien, la seule solution envisageable est donc le doublage des champs, 1 avec accent, l'autre sans..


ps : je ne trouve pratiquement aucune info sur la conception d'un moteur de recherche, auriez vous des pistes ?