Recherche sur la branche d'un thesaurus hiérachique
cs_oceanrider
Messages postés13Date d'inscriptionjeudi 18 novembre 2004StatutMembreDernière intervention20 juillet 2011
-
30 mars 2006 à 19:09
cs_oceanrider
Messages postés13Date d'inscriptionjeudi 18 novembre 2004StatutMembreDernière intervention20 juillet 2011
-
3 sept. 2006 à 21:58
Bonjour,
N'ayant une fois de plus pas pu trouver de réponse, je vous fais part de mon problème :
Je dispose d'une vidéothèque dans lesquels sont répertoriés mes films ainsi que ceux de mes amis. Chaque film peut être classé selon une liste d'autorité hiérarchisée.
ex. :
1 0 film
2 1 horreur, fantastique, SF
3 2 science-fiction
4 2 fantastique
5 2 horreur
6 1 western
7 6 spaghettis
8 6 classiques
9 6 crépusculaires
Tout mon problème est de réussir à effectuer une recherche sur une branche entière (ex. : western) sans pour autant multiplier les requêtes (1 requête sur western puis 1 sur spaghettis, 1 sur classiques, etc.).
Pour l'instant, mon idée était en reprenant le code de Titatou (http://www.phpcs.com/codes/ARBORESCENCE-RECURSIVE_30776.aspx) sur la construction d'un arbre récursif, non pas d'"afficher" la liste des catégories, mais de placer chaque valeur de cette liste dans un tableau ou dans une chaîne, afin de placer ce résultat dans une requête du type :
"SELECT titre,réal,année FROM Films,Categories WHERE idCat=XidCat AND ($critere);"
en remplaçant $critere par "idCategorie=6 OR idCategorie=7 OR idCategorie=8 OR idCategorie=9"
Voici ce que j'ai tenté (sans succès) jusqu'à présent :
function recur($tab,$pere)
{
//ballayage du tableau
for ($x=0;$x<count($tab);$x++)
{
//si un élément a pour père : $pere
if ($tab[$x][1]==$pere)
{
//on stocke la valeur dans un tableau
$liste[]=$tab[$x][0];
//et on recherche ses fils
recur($tab,$tab[$x][0]);
}
}
}
$reqCategories="SELECT idCategorie,idGenerique,categorie FROM Categories";
$resCategories=mysql_query($reqCategories) or die("Une erreur est survenue dans l'éxécution de la requête reqCategories !");
while($ligne=mysql_fetch_array($resCategories,MYSQL_ASSOC))
{
extract($ligne);
$data[] = array($idCategorie,$idGenerique);
}
$liste=recur($data,$formIdCat);
Le problème, c'est que je n'obtiens absolument rien.
Peut avez-vous une suggestion, peut être une toute autre méthode qui conviendrait mieux.
coucou747
Messages postés12303Date d'inscriptionmardi 10 février 2004StatutMembreDernière intervention30 juillet 201244 30 mars 2006 à 19:50
Salut,
function recur($tab,$pere)
{
//ballayage du tableau
for ($x=0;$x<count($tab);$x++)
{
//si un élément a pour père : $pere
if ($tab[$x][1]==$pere)
{
//on stocke la valeur dans un tableau
$liste[]=$tab[$x][0];
//et on recherche ses fils
recur($tab,$tab[$x][0]);
}
}
//Ta fonction ne renvoi rien, alors évidement...
du coup, liste ne contient rien... utilise soit un & devant les
arguments, soit un return à la fin de ta fonction
}
$reqCategories="SELECT idCategorie,idGenerique,categorie FROM Categories";
$resCategories=mysql_query($reqCategories) or die("Une erreur est survenue dans l'éxécution de la requête reqCategories !".mysql_error()
);
while($ligne=mysql_fetch_array($resCategories,MYSQL_ASSOC))
{
$data[] = array($ligne['idCategorie'],$ligne['idGenerique']);
}
$liste=recur($data,$formIdCat);
In a dream, I saw me, drop dead... U was there, U cried... It was just a dream, if I die, U won't cry, maybe, U'll be happy
Mon site (articles sur la programmation et programmes)
cs_oceanrider
Messages postés13Date d'inscriptionjeudi 18 novembre 2004StatutMembreDernière intervention20 juillet 2011 31 mars 2006 à 00:50
En réponse à Malalam, effectivement, mais cela limite la recherche à deux niveaux :
ainsi si je recherche tous les films (cat_id=1), je récupère ce qui correspond à "films", "western" et "horreur, SF, fantastique", mais pas ce qui a été classé dans "science-fiction", "fantastique", "horreur", "spaghetti", etc.
En outre, ma hiérarchie peut être plus profonde que dans l'exemple que j'ai donné ici et va jusqu'à 5 niveaux.
Sauf erreur de ma part, je suis donc bien obligé de procéder à une boucle récursive afin d'explorer les sous-niveaux.
Et pour ce qui est de la remarque sur le trés visible mysql_error(), il est effectivement plus sage de l'ajouter (mais pas indispensable).
En tous les cas, voici le code fonctionnel que j'obtiens finalement :
function recur($tab,$pere)
{
$liste=array();
//balayage du tableau
for ($x=0;$x<count($tab);$x++)
{
//si un élément a pour père : $pere
if ($tab[$x][1]==$pere)
{
//on stocke la valeur dans un tableau
$liste[]=$tab[$x][0];
//et on recherche ses fils
recur($tab,$tab[$x][0]);
}
}
//on renvoie la valeur
return $liste;
}
//recherche de toutes les catégories, leur ID et leur générique
$reqCategories="SELECT idCategorie,idGenerique,categorie FROM Categories";
$resCategories=mysql_query($reqCategories) or die("Une erreur est survenue dans l'éxécution de la requête reqCategories !");
while($ligne=mysql_fetch_array($resCategories,MYSQL_ASSOC))
{
extract($ligne);
//construction du tableau contenant toutes les catégories
$data[] = array($idCategorie,$idGenerique);
}
$liste=recur($data,$formIdCat);
//la fonction ne renvoie pas la catégorie séléctionnée, on l'intègre donc dans la valeur appelée plus tard comme critère de recherche
if($liste!="")
{
$critere=$formIdCat.' OR idCategorie='.implode($liste,' OR idCategorie=');
}
else
{
$critere=$formIdCat;
}
//requête finale recherchant les films de la catégorie ou des catégories filles
$reqRechSimp="SELECT idDoc,titre,titreOrig,annee,categorie FROM Documents,Categories WHERE X_idCategorie=idCategorie AND (idCategorie=$critere) ORDER BY $ordre LIMIT $limitDeb,$tailleGroupe";
$result=mysql_query($reqRechSimp) or die("Une erreur est survenue dans l'éxécution de la requête reqRechSimpCat ! ".mysql_error());
Voici la requête obtenue : SELECT
idDoc,titre,titreOrig,annee,categorie FROM Documents,Categories WHERE
X_idCategorie=idCategorie AND (idCategorie=2 OR idCategorie=3 OR idCategorie=4 OR idCategorie=5) ORDER BY titre
LIMIT 0,20
Merci à tous pour vos contributions, en espérant que mes propres déboires pourront en aider certains.
cs_oceanrider
Messages postés13Date d'inscriptionjeudi 18 novembre 2004StatutMembreDernière intervention20 juillet 2011 3 sept. 2006 à 21:58
Petite mise à jour : en fait, je viens de m'apercevoir que cette fonction n'est pas pleinement opérationnelle.
En effet, avec le return cette fonction ne parvient pas à renvoyer les Id au dela du deuxième niveau de la hiérarchie (elle trouve les spécifiques du terme recherché, mais pas les spécifiques des spécifiques). Aussi je l'ai modifiée de façon à ce qu'elle soit pleinement opérationnelle en remplaçant le return par un passage des arguments par référence.
function recur($tab,$pere,&$valeurs)
{
//balayage du tableau
for ($x=0;$x<count($tab);$x++)
{
//si un élément a pour père : $pere
if ($tab[$x][1]==$pere)
{
//on stocke la valeur dans un tableau
$valeurs[]=$tab[$x][0];
//et on recherche ses fils
recur($tab,$tab[$x][0],&$valeurs);
}
}
}
//recherche de toutes les catégories, leur ID et leur générique
$reqCategories="SELECT idCategorie,idGenerique,categorie FROM Categories";
$resCategories=mysql_query($reqCategories) or die("Une erreur est survenue dans l'éxécution de la requête reqCategories !".mysql_error());;
while($ligne=mysql_fetch_array($resCategories,MYSQL_ASSOC))
{
//construction du tableau contenant toutes les catégories
$data[] = array($ligne['idCategorie'],$ligne['idGenerique']);
}
recur($data,$formIdCat,$liste);
Ainsi, $liste est exploitable et contient cette fois tous les termes spécifiques à celui recherché.