Afficher les articles relatifs à celui consulté en PHP/MySQL

WRInaute accro
Salut,

Je voudrais afficher sur mes articles un bloc "Vous aimerez également :" suivi d'une liste de 5 articles pas forcément de la même catégorie dans le site mais dont les titres laissent à penser qu'ils sont similaires.

Exemple : titre "L'Audi A8 W16, missile de luxe"
et que ça puisse me sortir dans "Vous aimerez également :" l'article que j'ai écris le mois dernier "Bugatti Veyron W16 : l'action de Total monte en flèche". :mrgreen:

Quelqu'un aurait un tuto ou une piste technique pour sortir ça ?

Un grand merci

PS : j'imagine que ça fonctionne à grand renforts d'explode et de like % ?
 
WRInaute accro
Je gérerais davantage ça en créant un système d'association d'article, un article pouvant être associé à n autres.

Ou si tu veux automatiser cela (ce qui me semble être le cas vu qu'une partie des titres est identique) ça peut en effet se faire via une recherche sur les autres titres d'articles présent dans ta base, après avoir nettoyé ceux-ci des mots inutiles (pronoms, déterminants, conjonctions diverses).
 
WRInaute accro
Merci c'est ce que j'ai commencé à faire. J'ai déjà 600 articles et je ne peux/vais pas les associer à la main ni en automatique.
Je suis parti sur du str_replace pour virer les "le, la, les, des, du, au" etc., explode, like et ça devrait rouler.
 
WRInaute accro
Le souci c'est qu'en automatisant, tu risques à un moment d'avoir des listes d'articles non négligeables de conseillés en-dessous d'un article.
 
WRInaute passionné
Regarde la méthode utilisé par le plugin wordpress "related post".
Je pense qu'il faut partir sur des % LIKE et des bons gros preg_match, mais par la suite, les faire à la main pourrait être pas mal.

Edit: j'ignore quel module c'est sur PHPBB, mais matte un peu en dessous de la réponse "sur ce thème".

Un moteur google peut être pas mal sinon pour faire ce genre de chose (à vérifier bien sûr)
 
WRInaute accro
UsagiYojimbo a dit:
Le souci c'est qu'en automatisant, tu risques à un moment d'avoir des listes d'articles non négligeables de conseillés en-dessous d'un article.
Non tinquite, je croise avec d'autres critères et je limite a 5 articles.
 
WRInaute impliqué
Perso je verrai bien en premier un traitement sur le titre qui remplace tous les caracteres non alphanumeriques par des espaces, ensuite un explode sur les caracteres d'espace, et tu te construis une requete avec une boucle for et des LIKE avec le tableau que t'as obtenu avec l'explode (en ne gardant que les mots de plus de deux caracteres par exemple).

Autre chose pour la précision tu peux additionner le nombre de mots qui matchs bien ;) (je garanti pas la rapidité, c'est juste pour te donner des idées)
Pour exemple essaye une requete du style :
Code:
SELECT *, (TITRE LIKE '%audi%') AS TEST1, (TITRE LIKE '%a8%') AS TEST2, (TITRE LIKE '%w16%') AS TEST3 FROM `tatable` ORDER BY (TEST1+TEST2+TEST3) DESC
t'as juste à remplacer tatable par le nom de ta table d'articles, et TITRE par le champ qui correspond aux titres de tes articles, et les mots que tu recherches. Je t'ai mis les mots audi, a8, et w16 pour rester dans ton exemple ;)

Si t'as beaucoup d'affluence regarde au niveau temps de réponse d'une telle requête...
Après ça dépend de ton serveur et du nombre de tes articles, mais les LIKE c'est pas forcement très rapide...
Fais des tests, si ca te pénalise trop tu peux aussi précalculer et enregistrer en bdd dans un nouveau champ pour chaque article... genre quand tu créé un article ca te calcul direct les articles similaires, et t'enregistres les id des articles séparés par des virgules dans un champ tinytext.
Limite si tu veux que ce soit actualisé tu te fais un script en tache cron qui se lance une fois de temps en temps en pleine nuit et qui recalculera tout ça...
 
WRInaute accro
j'utiliserais plutôt des regexp dans la requête : ça éviterait ainsi de sélectionner des morceaux de mots, du genre like "%audi%" qui te ressortirait aussi "bon matériel audio" :wink:
 
WRInaute impliqué
bin faut tester...
par contre moi j'aurais plutot mis un preg_replace pour retirer les caractères non alpha numériques...

Code:
$ret=preg_replace("/\W/"," ",$tonTitre);

tu compte te faire un tableau des caracteres à retirer avec ton str_replace?


[edit] benchmark entre str-replace et preg_replace : http://www.php-scripts.com/php_diary/011303.php3
 
WRInaute accro
Merci mais je ne comprends rien aux regex.

Prenons un exemple :
Allumettes de pomme de terre façon Cuisinetoo (reblochon)
Quel regex pour en sortir
allumettes
pommes de terre
reblochon

J'ai bien sur isolé pomme de terres par un str_replace (je le remplace par un chiffre).

?
 
WRInaute accro
dans leur 1° benchmark, ils n'ont pas utilisé str_replace de façon efficiente, ce qui fait que sa performance était moindre. En utilisant str_replace(array("-","."," ","(",")"),"", $phone); ils auraient gagné un facteur de 5 quasiment
milkiway a dit:
Allumettes de pomme de terre façon Cuisinetoo (reblochon)
Quel regex pour en sortir
allumettes
pommes de terre
reblochon
Code:
select * from tatable where title regexp "(allumettes|pommes de terre|reblochon)"
après, il faut voir pour gérer les pluriels, etc...
 
WRInaute impliqué
Leonick a dit:
dans leur 1° benchmark, ils n'ont pas utilisé str_replace de façon efficiente, ce qui fait que sa performance était moindre. En utilisant str_replace(array("-","."," ","(",")"),"", $phone); ils auraient gagné un facteur de 5 quasiment

En effet y'a moyen de discuter sur son test.
Par contre c'est pas évident de se faire un tableau avec tous les caractères non alpha qu'il pourrait utiliser dans un titre. là il faut rajouter ! ; ? " = + à ta liste je pense, et plus la liste grossi plus ca prendra du temps. Comparé à un \W je pense que ce serait quand même bien de tester...


milkiway> t'auras du mal à ressortir l'espression "pomme de terre", t'auras plutot "pomme", "de", et "terre".

Code:
<?php

$txt="c'est la fête, et on s'amuse comme des fous!!";

$ret=preg_replace("/\W/"," ",$txt); // a reflechir si str_replace ou preg_replace
$ret2=explode(" ",$ret);

print_r($ret2);

?>
 
WRInaute accro
Merci.
Comme dit, avant le regex, je remplace tout simplement "pommes de terre" par "01" ainsi ce n'est pas touché ;)
Par contre, ta fonction c'est un explode en 20 fois plus gourmand non?
 
WRInaute impliqué
non preg replace c'est comme un str_replace mais avec une expression reguliere. En gros le \W veut dire tous les caracteres non alpha numerique (c'est l'inverse de \w qui veut dire tous les caracteres alphanum).
Donc là le preg_replace remplace tous les caracteres non alphanum par des espaces.
Ensuite t'as un explode qui coupe à chaque fois que y'a un espace.
Et ensuite dans ta boucle for pour créer ta requete mysql t'a juste à récupérer les éléments du tableau avec un petit if pour filtrer les entrées nulles ou alors de 1 caractère.

[edit]
Bon je t'ai fais un truc rapidos pour t'expliquer ce à quoi je pensais.

Code:
<?php

$txt="c'est la fête, et on s'amuse comme des fous!!";

$ret=preg_replace("/\W/"," ",$txt);
$ret2=explode(" ",$ret);

print_r($ret2);

$query="debutRequete WHERE";
$n=count($ret2);
$nn=0;
for ($i=0;$i<$n;$i++) {
    if (strlen($ret2[$i])>1) {
        if ($nn>0) { $query.=" OR"; }
        $query.=" (test avec '".$ret2[$i]."')";
        $nn++;
    }
}

echo "<br/>".$query;

?>
 
WRInaute accro
Ok merci.

Comment je peux faire pour virer dans $ret2 de ton exemple, toutes les entrées vides et celles de moins de trois lettres ?
Ou alors je le fais carrément d'office dans le premier regex ?
 
WRInaute accro
C'est super sympa à vous, merci RiPso, je me suis basé sur ton script que j'ai modifié (j'ai ... viré le preg_replace car certains de mes titres contiennent des chiffres...) et ça a l'air de me donner satisfaction. Reste plus qu'à créer cette requête et faire un bon système de cache...
 
WRInaute accro
Merci pour tout. Par contre je suis obligé de faire une requête par terme ?
Si je sépare les termes par des OR comme j'ai pas mal de résultats rien que pour le premier et que je ne veux afficher que 5 articles relatifs, les autres ne sont pas pris en compte.
Je voudrais que ça sorte des résultats pertinents.
Par exemple trois mots représentant le contenu : gratin, pâte, viande hachée
je voudrais que ça me sorte les autres gratins de pâtes par exemple, pas juste les gratins ou juste les pâtes ou juste la viande hachée.

Comment je peux faire pour ça ?
J'ai pas besoin d'un algo à la Google mais bon ;)
Je regarde bien sur du côté de FULL TEXT (pour ceux que le sujet intéresse : http://dev.mysql.com/doc/refman/5.0/fr/fulltext-search.html ) seulement il ne trouve rien. Je ne comprends pas tout.
 
WRInaute impliqué
Et bien il te suffit d'adapter avec la requête que je t'ai donné plus haut.
Ça comptera 1 à chaque fois qu'il trouvera un des mots et ca classera en fonction de la somme des résultats.

Ensuite si ça te prends trop de temps à l'exécution je te conseil d'enregistrer le résultat à chaque fois que tu créé un article.
 
WRInaute accro
Et bien pourtant je viens de le finir et le résultat est au delà de mes espérances :D
La pertinence, pour ce que j'en fais, est excellente :D
Alleluhuia !

Merci à tout le monde pour l'aide, j'ai maintenant un système de tags automatisé ne renvoyant que des résultats pertinents et un système d'articles qui peuvent intéresser le lecteur qui fonctionne à merveille.

J'adore le PHP et MySQL (même si ça devient vite lent).
 
WRInaute accro
Si tu pouvais afficher ta solution, cela pourrait aider d'autres webmasters qui souhaiteraient avoir le même type de solution
 
Discussions similaires
Haut